字符串或文件的分隔符:使用 csv.reader() 而不是 csv.Sniffer()

Posted

技术标签:

【中文标题】字符串或文件的分隔符:使用 csv.reader() 而不是 csv.Sniffer()【英文标题】:delimiter for string or file: using csv.reader() and not csv.Sniffer() 【发布时间】:2014-10-21 15:37:57 【问题描述】:

背景:来自亚马逊 S3 的流式日志文件。从压缩文件中,经过几步,我得到了一个类似文件的对象。对于 gzip 压缩的文件,我在流中解压了一个块,它是一个字符串,然后使用str.splitlines() 来获取行列表。

csv.reader 接受任何带有迭代器协议的东西,比如文件和列表。但是,对于文件,我需要在一切完成后file.close()。然后,我拥有的文件在解压缩和解压缩后变成 csv 和 tsv 文件。逗号或制表符分隔。

delims = [',','\t']

对于 zipfile,由于中间步骤是制作没有 seek() 函数的 ZipExtFile,所以我不能使用 csv.Sniffer。对于 gzip 文件,它们被流式传输并成为行列表。

在调用csv.reader 时,如何动态确定使用哪个分隔符?我目前正在使用下面的代码 (based off this)。理想情况下,我向此发送teststr,然后调用csv.reader(csvfile, delimiter = k)

但是,由于两种类型的输入都没有seek() 函数,我如何获取文件/列表的样本进行测试,然后返回到文件的开头?

teststr = 'how,-do,-you,-dynamically,-identify,-unknown,-delimiters,-in,-a,-data'

def find_delimiter(teststr):
    # how-do-you-dynamically-identify-unknown-delimiters-in-a-data-file
    possible = [',','\t','-']
    count = 

    for c in teststr:
        if c in possible: count[c] = count.get(c,0) + 1

    delim = [key for key,val in count.iteritems() if val == max(count.values())]

    if len(delim) == 1: 
        delim = delim[0]
    else:
        print delim
        delim = None
    return delim

k = find_delimiter(teststr)
print k

【问题讨论】:

你不能把文件从那个字符串缓冲区加载到内存中吗? @SylvainLeroux (抱歉提前无知)我不知道怎么做,也不知道怎么可能。我想我不是在加载文件,而是从 AWS S3 获取它们(差异?),我认为流式传输就像把它放在内存中然后读出一点?此外,我正在处理> 100s MB 的文件,最后计算了近24000 个文件。不知道这是否相关,但也只需要每个文件中的几行。 【参考方案1】:

个人解决方案总结

决定这个小方法有效,所以我改变了我的方法:我打开或流式传输文件,暂时忽略csv.reader()(并希望大多数数据在换行行为中表现良好,它应该 to be) 使用字符串的.readline() 方法来抓取几行。

然后将其发送到上面的find_delimiter 方法,然后将行和返回的分隔符贯穿csv.reader()

【讨论】:

以上是关于字符串或文件的分隔符:使用 csv.reader() 而不是 csv.Sniffer()的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python csv.reader 从文本文件中删除 html 格式“>”

读写CSV文件

python读写csv文件

Python——csv txt文件读写

下载数据)

用python处理文本数据 学到的一些东西