【问题标题】:Reading CSV file in Pandas with double 'double quotes' and embedded commas使用双“双引号”和嵌入式逗号在 Pandas 中读取 CSV 文件
【发布时间】:2019-10-10 14:31:33
【问题描述】:

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

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

我希望正确解析的数据帧像

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 有逗号时,我才会遇到解析问题。

【问题讨论】:

标签: python pandas csv


【解决方案1】:

我不确定 pandas 是否可以自己执行此操作,因为您的数据中也有未转义的分隔符和引号。

但是,您应该能够在使用正则表达式修改数据后通过转义作为字段一部分的引号来解析它。

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='\\')

正则表达式查找不在每行开头(?&lt;!^) 或结尾(?!$) 的引号,以及不属于每个字段开头(?&lt;!,") 和结尾(?!,") 的引号

【讨论】:

    【解决方案2】:

    这应该对你有用

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

    【讨论】:

    • 谢谢!尽管我能够读取该文件,但使用提到的分隔符会导致在读取列时为每个字段添加额外的引号。将 df 写入 CSV 文件会得到以下输出,第一行如下所示:"""10","""""AB""","""ABCD","""abcd"""
    【解决方案3】:

    预处理不一定是坏事。如果使用系统管道完成,它不会增加太多开销(就像上面的 StringIO 一样)。它还可以节省大量时间来解决一些已知问题(例如 DOS CR、EOF 处没有 EOL、中间为 NULL 字节等,具体取决于您的系统)。

    对于这种情况 + 一些其他常见问题,例如额外的引号、空格、逗号、嵌入的逗号。虽然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)
    

    带有 cmets 和问题的输入文件

    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']
    

    【讨论】:

      猜你喜欢
      • 2019-03-28
      • 2017-09-28
      • 1970-01-01
      • 2021-10-28
      • 1970-01-01
      • 2019-10-31
      • 1970-01-01
      • 1970-01-01
      • 2019-05-02
      相关资源
      最近更新 更多