在pandas中读取包含逗号和特殊字符的CSV文件时遇到问题

8

我正在尝试使用pandas读取csv文件,其中有一个名为Tags的列,其中包含用户提供的标签,例如-, "", '',1950年代,16世纪等标签。由于这些是用户提供的,因此也会有许多错误输入的特殊字符。问题在于,我无法使用pandas read_csv打开csv文件。它显示错误:Cparser,解析数据时出现错误。有人能帮我将csv文件读入pandas吗?


2
为了加快进程,你能否发布一些给你带来困扰的文件中的例行代码? - DSM
标签字段是否被引用?如果没有,你将会遇到一些困难。 - Wes McKinney
pandas._parser.CParserError: 解析数据时出错。C错误:在第3行中期望4个字段,但看到了8个。 标签字段中的第3列是逗号。标签字段未被引用。是否有不使用引号引用标签列的解决方法? - user1992696
Urf. 如果我没记错的话,你的列是“标签,用户,质量,聚类ID”,对吗?其他三个是否也是这样(没有未引用的逗号)?如果是这样,那么我们可以通过循环每一行,取最后三个,并将其余所有内容放入标签字段中来挽救它。 - DSM
是的,没错,列就像你所提到的那样。用户是一个URI,例如:http://xyz.nl/user_001。cluster_id只包含1-500的值。Quality有:good、bad、usefulness-useful、usefulness-not_useful等。只有tags字段包含带有逗号的单元格和单元格中包含诸如17th、red、flower之类的单词。这些单元格导致了问题。 - user1992696
1个回答

9

好的。从一个格式不良的CSV开始,我们无法读取:

>>> !cat unquoted.csv
1950's,xyz.nl/user_003,bad, 123
17th,red,flower,xyz.nl/user_001,good,203
"",xyz.nl/user_239,not very,345
>>> pd.read_csv("unquoted.csv", header=None)
Traceback (most recent call last):
  File "<ipython-input-40-7d9aadb2fad5>", line 1, in <module>
    pd.read_csv("unquoted.csv", header=None)
[...]
  File "parser.pyx", line 1572, in pandas._parser.raise_parser_error (pandas/src/parser.c:17041)
CParserError: Error tokenizing data. C error: Expected 4 fields in line 2, saw 6

我们可以制作更美观的版本,利用最后三列的良好特性:

import csv

with open("unquoted.csv", "rb") as infile, open("quoted.csv", "wb") as outfile:
    reader = csv.reader(infile)
    writer = csv.writer(outfile)
    for line in reader:
        newline = [','.join(line[:-3])] + line[-3:]
        writer.writerow(newline)

它会产生

>>> !cat quoted.csv
1950's,xyz.nl/user_003,bad, 123
"17th,red,flower",xyz.nl/user_001,good,203
,xyz.nl/user_239,not very,345

然后我们可以阅读它:

>>> pd.read_csv("quoted.csv", header=None)
                 0                1         2    3
0           1950's  xyz.nl/user_003       bad  123
1  17th,red,flower  xyz.nl/user_001      good  203
2              NaN  xyz.nl/user_239  not very  345

我建议从源头开始解决这个问题,让数据以可容忍的格式呈现。不应该依赖于这样的技巧,如果不及时修复,可能会变得无法挽回。


你好, 谢谢你提供的解决方案。你能解释一下这行代码的作用吗? newline = [','.join(line[:-3])] + line[-3:] - user1992696
1
line[:-3]是一个列表,它包含除最后三个元素以外的所有元素。 ','.join(some_sequence)使用字符串, -- 逗号 -- 将它们组合在一起。这是因为如果你把print line放在内部循环里面,你会发现CSV读取器不知道如何不把17th,red,flower分成多个元素,所以我必须重新将其组合成一个术语。方括号[]使其成为一个单元素列表。第二项line[-3:]表示“从结尾开始的前三个元素”的所有列表元素。所以实际上它只是“用除了最后三个元素以外的所有元素重新组合第一个元素来创建一个新的列表”。 - DSM
我真的需要看到一些问题案例才能说得更多。 - DSM
当我运行代码时,它没有出现错误,但只是将infile复制到outfile。一些标签的例子包括:[,],[*man],[12a44],[17thcentury, flower, red], [1920's],[19th century,painting], [3/4 angle][age?]。这些主要是在线绘画收藏中由用户输入的标签。有些标签只是逗号,并且包含特殊字符的混合。 - user1992696
我试图打印它们,这是我得到的结果: line ->['zen', 'http://steve.nl/user_4027', 'usefulness-useful', '500'] newline->['zen', 'http://steve.nl/user_4027', 'usefulness-useful', '500']但如果我改变newline = [','.join(line[:-2])] + line[-3:],那么我得到 line ->['zen', 'http://steve.nl/user_4027', 'usefulness-useful', '500'] newline ->['zen,http://steve.nl/user_4027', 'http://steve.nl/user_4027', 'usefulness-useful', '500'] - user1992696
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接