首页 > 解决方案 > 如何使用包含引号并使用多个分隔符的 pandas 读取 CSV 文件

问题描述

我正在做一个项目,我在 for 循环中读取多个 CSV 文件,一些文件包含一个分号 (;) 作为分隔符,而其他文件包含一个逗号 (,)。我需要将标题保留在所有 CSV 文件中,因此我不能使用固定标题。

我在处理一个 CSV 文件时遇到问题,尤其是其中包含某些值的引号,例如

第 1 列,第 2 列,第 3 列,第 4 列 12531,ABCDE,"12523,2",EXAMPLE 52313,ADE,12302,EXAMPLE

使用逗号作为分隔符不起作用,因为我最终得到 15 个值而不是 13 个导致解析错误。

在记事本中打开文件时,我看到对于包含带引号的值的行,双引号被添加到所述值以及逗号被添加到行的开头和结尾:

第 1 列,第 2 列,第 3 列,第 4 列 "12531,ABCDE,""12523,2"",EXAMPLE" 52313,ADE,12302,EXAMPLE

我想像其他文件一样成功处理这个文件,同时保持使用的能力:

我尝试用 . 替换引号之间的 , 。但这并不能消除将引号添加到行首和行尾的问题,而且它根本不起作用,因为它原来是两个引号..

extension = 'csv'
all_filenames = [i for i in glob.glob('*.{}'.format(extension))]

for csv in all_filenames:
    file = open(csv, 'r')
    content = file.read()
    content = re.sub(r'(?!(([^"]*"){2})*[^"]*$),', '.', content)
    combined_csv = pd.read_csv(csv, sep=";|,", engine="python")
    appended_data.append(combined_csv)

appended_data = pd.concat(appended_data)

标签: pythonregexpandascsvre

解决方案


我建议用一次出现替换逗号之前或之后的多个块",然后使用pd.read_csv参数quotechar='"'来确保引用的字段最终出现在单个列中:

content = re.sub(r'(?<![^,])"{2,}|"{2,}(?![^,])', '"', content)
#...
combined_csv = pd.read_csv(csv, sep=";|,", engine="python", quotechar='"')

正则表达式详细信息

  • (?<![^,])- 在当前位置之前,必须有逗号或字符串开头
  • "{2,}- 两个或更多"字符
  • |- 或者
  • "{2,}- 两个或更多"字符
  • (?![^,])- 紧跟在当前位置之后,必须有逗号或字符串结尾。

推荐阅读