阅读带有双“双引号”和嵌入逗号的Pandas中的CSV文件

xpcnnkqh  于 2023-02-27  发布在  其他
关注(0)|答案(4)|浏览(230)

我需要在Pandas中读取一个CSV文件,其中包含以下格式的数据(其中一个字段为双“双引号”)

"column1","column2","column3","column4"
"10",""AB"","ABCD","abcd"
"11",""CD,E"","CDEF","abcd"
"12",""WER"","DEF,31","abcd"

我希望正确解析的 Dataframe 如下所示

column1  column2  column3   column4
10       AB       ABCD      abcd
11       "CD,E"   CDEF      abcd
12       WER      "DEF,31"  abcd

我试着用

df= pd.read_csv('sample.txt',quotechar='""', quoting=csv.QUOTE_ALL)

以及

df= pd.read_csv('sample.txt',quotechar='"', quoting=csv.QUOTE_ALL)

但是

TypeError: "quotechar" must be a 1-character string

以及

pandas.errors.ParserError: Error tokenizing data. C error: Expected 4 fields in line 3, saw 5

有没有一种方法可以让我直接读取这个文件,而不必预处理和删除数据中的双“双引号”?
column2没有逗号时,我可以用一些额外的引号读取数据,这些引号可以在进一步的处理步骤中替换。只有当column2有逗号时,我才会遇到解析问题。

wdebmtf2

wdebmtf21#

我不确定Pandas是否能自己完成这个任务,因为你的数据中也有未转义的分隔符和引号。
但是,您应该能够在使用regex修改数据之后解析它,方法是转义字段中的引号。

import re
from io import StringIO

data = """
"column1","column2","column3","column4"
"10",""AB"","ABCD","abcd"
"11",""CD,E"","CDEF","abcd"
"12",""WER"","DEF,31","abcd"
"""

data = re.sub('(?<!^)"(?!,")(?<!,")(?!$)', '\\"', data, flags=re.M)

pd.read_csv(StringIO(data), escapechar='\\')

如果正在阅读文件,则:

with open('path/to/csv', 'r') as f:
    data = re.sub('(?<!^)"(?!,")(?<!,")(?!$)', '\\"', f.read(), flags=re.M)
    df = pd.read_csv(StringIO(data), escapechar='\\')

正则表达式查找不在每行的开始(?<!^)或结束(?!$)处的引号,以及不在每个字段的开始(?<!,")和结束(?!,")处的引号

vlurs2pr

vlurs2pr2#

预处理不一定是坏事。如果使用系统管道完成,它不会增加太多的开销(就像上面的StringIO)。它还可以节省大量的时间来解决一些已知的问题(例如DOS CR,EOF处没有EOL,中间为空字节,等等,这取决于您的系统)。
对于这种情况+一些其他常见的问题,如额外的引号,空格,逗号,嵌入逗号。虽然pandas确实有一个参数doublequote,它不够灵活。
使用系统管道,对于Linux上的大型文件应该是有效的

import os
df = pd.read_csv(
  os.popen('sed -r "s/^\s+|(^[,[:space:]]*|\s*)(#.*)?$//g; s/\s+,/,/g; s/\\"\\"/\\"/g" %s' % fname),
    quotechar='"', skipinitialspace=True)

或:使用python管道

import re
from io import StringIO
with open(fname) as f:
  data = re.sub('""', '"', re.sub('[ \t]+,', ',',
    re.sub('^[ \t]+|(^[ \t,]*|[ \t]*)(#.*)?$', '', f.read(), flags=re.M)))
  df = pd.read_csv(StringIO(data), quotechar='"', skipinitialspace=True)

包含注解和问题的输入文件

a, b, c, d         # header w/ trailing spaces
,, ,,,,            # commas + spaces, no data
# extra space before data
  1, 2, 3.5, 4k     
3, " 5 " , 7.6, "n, m" # extra spaces, comma inside
10, "20" , 30.5, w z
40, 60, 75, ""x, q""   # double quoting

输出:

a   b     c     d
0   1   2   3.5    4k
1   3   5   7.6  n, m
2  10  20  30.5   w z
3  40  60  75.0  x, q

它现在是干净的和正确的格式:

a int64
b int64
c float64
d object

list(df['d']):  ['4k', 'n, m', 'w z', 'x, q']
xe55xuns

xe55xuns3#

这个应该能帮你

df =pd.read_csv("so.txt",encoding='utf-8', names=["column1","column2","column3","column4"],sep='",',header=0,quoting=csv.QUOTE_ALL)
1l5u6lss

1l5u6lss4#

我尝试了其他的答案,但是一个不起作用,另一个把我的文本搞得一团糟。我最终创建了我的解决方案。我发现一个好的分隔符应该是**",但是我不能用它来处理Pandas,库就是不起作用。
所以这段代码是逐行读取的,按
"拆分,**创建为pd.Series,因为我只能使用Series在 Dataframe 中追加。

df = pd.DataFrame()

i = 0
with open("teste.csv", 'r') as arquivo:
    for linha in arquivo:
        i = i+1
        print(i)
        colunas = pd.Series( linha.split("\",") )        
        df = df.append(colunas, ignore_index=True)

需要注意的是,这段代码处理70000行代码需要一些时间,但对我和OP示例来说,它工作得非常完美。

相关问题