这个答案适用于手动输入字符串的情况,而不是从其他地方读取字符串的情况。
传统的变宽CSV对于将数据存储为字符串变量来说是不可读的。特别是在
.py
文件中使用时,应考虑使用固定宽度的管道分隔数据。各种IDE和编辑器可能有插件,可以将管道分隔文本格式化为整齐的表格。
使用
read_csv
。
将以下内容存储在实用程序模块中,例如
util/pandas.py
。函数的docstring中包含了一个示例。
import io
import re
import pandas as pd
def read_psv(str_input: str, **kwargs) -> pd.DataFrame:
"""Read a Pandas object from a pipe-separated table contained within a string.
Input example:
| int_score | ext_score | eligible |
| | 701 | True |
| 221.3 | 0 | False |
| | 576 | True |
| 300 | 600 | True |
The leading and trailing pipes are optional, but if one is present,
so must be the other.
`kwargs` are passed to `read_csv`. They must not include `sep`.
In PyCharm, the "Pipe Table Formatter" plugin has a "Format" feature that can
be used to neatly format a table.
Ref: https://dev59.com/aGEh5IYBdhLWcg3wRRqh#46471952/
"""
substitutions = [
('^ *', ''),
(' *$', ''),
(r' *\| *', '|'),
]
if all(line.lstrip().startswith('|') and line.rstrip().endswith('|') for line in str_input.strip().split('\n')):
substitutions.extend([
(r'^\|', ''),
(r'\|$', ''),
])
for pattern, replacement in substitutions:
str_input = re.sub(pattern, replacement, str_input, flags=re.MULTILINE)
return pd.read_csv(io.StringIO(str_input), sep='|', **kwargs)
无法使用的替代方法
以下代码无法正常工作,因为它在左右两侧都添加了空列。
df = pd.read_csv(io.StringIO(df_str), sep=r'\s*\|\s*', engine='python')
关于
read_fwf
,它
实际上并没有使用read_csv
接受和使用的那么多可选的kwargs。因此,在处理管道分隔数据时不应使用它。
pd.read_table()
是一个等价的函数,只是命名略有改进:df = pd.read_table(TESTDATA, sep=";")
。 - wkzhupandas.compat.StringIO
。这样我们就不需要单独导入StringIO
了。然而根据http://pandas.pydata.org/pandas-docs/stable/api.html?highlight=compat,pandas.compat
包被认为是私有的,所以现在保留原始答案。 - Emil Lpandas.compat
的方式仅适用于 pandas 0.25 之前的版本,但现在会引发 ImportError 错误。 - Mike T