在pandas中忽略列数据中的分隔符
我有一个输入的CSV文件,除了我们用数据框对象修改的字段外,不应该被pandas自动修改。比如,我们使用逗号(,)作为分隔符。这个文件可能包含:
- 没有引号的数据:
- plah
- blah
- 引号可以随意出现,次数也不固定。比如:
- "plah"
- ""plah
- """plah"
- ""pl""ah""
- 单个列的数据中可能包含分隔符(但这些数据的左右两边一定会有引号)。比如:
- "plah,blah"
- ""plah"",""blah"
在这些情况下,pandas不应该丢失引号,也不应该把单个引号列中的逗号(,)当作是不同的列。
可复现的代码:
# Input file
csv_data = '''A,B,C,D,E
234,mno,C22,U,
567,pqr,"C3""",U,5555
999,abc,"C99",D,9999
678,bns,"C6,C7",F,6666
789,bcd,""""C77,T,7777
'''
# Load CSV data into dataframes
df = pd.read_csv(StringIO(csv_data), header=0, dtype=str, keep_default_na=False, engine='python', sep=',', quoting=3)
df.to_csv('output.txt', sep=',', index=False, header=True, quoting=3)
我遇到了错误:
ParserError: Expected 5 fields in line 5, saw 6
期望结果:
A,B,C,D,E
234,mno,C22,U,
567,pqr,"C3""",U,5555
999,abc,"C99",D,9999
678,bns,"C6,C7",F,6666
789,bcd,""""C77,T,7777
1 个回答
2
你关闭了引号功能(quoting=3
/quoting=csv.QUOTE_NONE
),但是数据的第四行
678,bns,"C6,C7",F,6666
很可能应该有一个被引号包围的字段 "C6,C7"
。
所以你应该这样读取它:
678 bns "C6 C7" F 6666
你不能把引号当作分隔符,同时又把它们保留在导入的数据里。
主要的问题是你的CSV文件不合法。你要么使用引号作为引号字符,要么使用普通字符,它们不能同时存在。
一个解决办法是,如果你只有这一种双重使用引号的情况,可以尝试用两种模式读取文件两次,然后用concat
把它们合并,再用drop_duplicates
去掉重复项,除了C
列:
df1 = pd.read_csv(StringIO(csv_data), header=0, dtype=str,
keep_default_na=False, engine='python', sep=',',
quoting=3, on_bad_lines='skip')
df2 = pd.read_csv(StringIO(csv_data), header=0, dtype=str,
keep_default_na=False, engine='python', sep=',',
quoting=0, on_bad_lines='skip')
out = (pd.concat([df1, df2])
.drop_duplicates(['A', 'B', 'D', 'E'], ignore_index=True)
)
注意,这样做不会保持原始行的顺序。
输出:
A B C D E
0 234 mno C22 U
1 567 pqr "C3""" U 5555
2 999 abc "C99" D 9999
3 789 bcd """"C77 T 7777
4 678 bns C6,C7 F 6666