字符串或文件的分隔符:使用 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()的主要内容,如果未能解决你的问题,请参考以下文章