使用pd.read_csv自动检测CSV文件中的分隔符

8

有没有一种方法让read_csv自动检测分隔符?numpy的genfromtxt可以做到这一点。

我的文件中使用单个空格、双个空格和制表符作为分隔符。 genfromtxt()可以解决这个问题,但比pandas的read_csv慢。

有什么想法吗?

3个回答

14

另一种选择是使用内置的CSV嗅探器。如果CSV文件很大,我建议与只读取一定数量的字节混合使用。

import csv

def get_delimiter(file_path, bytes = 4096):
    sniffer = csv.Sniffer()
    data = open(file_path, "r").read(bytes)
    delimiter = sniffer.sniff(data).delimiter
    return delimiter

5
为了更好的控制,我使用一个名叫detect_delimiter的Python模块。它是来自Python项目的。请参见https://pypi.org/project/detect-delimiter/。它已经存在一段时间了。和所有代码一样,在部署之前,您应该使用您的解释器进行测试。我已经测试过Python版本3.8.5。
请参见下面的代码示例,其中自动检测到分隔符,并从该方法的输出中定义变量delimiter。然后,使用sep=delimiter读取CSV文件。我已经尝试过以下几个分隔符,但其他分隔符也应该可以工作:;、,、|。
它不适用于多字符分隔符,例如“,”。
注意!此方法对于检测格式错误的CSV文件无能为力。在输入文件包含;和,的情况下,该方法将返回,作为检测到的分隔符。
from detect_delimiter import detect
import pandas as pd

filename = "some_csv.csv"
with open(filename) as f:
    firstline = f.readline()
    delimiter = detect(firstline)

records = pd.read_csv(filename, sep = delimiter)

有一个拼写错误,它应该是“delimiter”,而不是“deliminter”。 - juanbretti
detect_delimiter 不考虑引号和转义,因此如果分隔符由于转义而出现更多次数,则很容易错过正确的分隔符。它按照逗号、分号、冒号、竖线和制表符的顺序计算前5行中每个字符的出现次数。如果默认字符在每行中出现的次数相等,则返回该字符,否则返回第一个出现次数相等的字符,...否则以同样的方式测试最常出现的字符,如果仍然失败,则返回默认值。 - Herbert

5

选项1

使用delim_whitespace = True

df = pd.read_csv('file.csv', delim_whitespace=True)

选项2

将正则表达式传递给sep参数:

df = pd.read_csv('file.csv', sep='\s+')

这相当于第一个选项。


有关pd.read_csv的文档。


太棒了。选项#2对于csv文件也非常有效。 - SEU
1
如果存在不将一个字段与另一个字段分开的空格,则这些选项都无法工作。例如,如果您有一个制表符分隔的文件,并且在字段内存在空格,则几乎必须执行sep='\t' - Adrian Keister
1
@AdrianKeister 这是正确的,但问题涉及数字数据,所以我们应该没问题。但对于字符串数据,这是需要注意的。 - cs95
如果能更清楚地表明我们只讨论数字数据,或者提供适用于一般CSV数据的解决方案,那将非常有用。 - baxx

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