在python中计算30GB + csv文件中双引号外的新行数
Posted
技术标签:
【中文标题】在python中计算30GB + csv文件中双引号外的新行数【英文标题】:Count number of new lines outside double quotes in a 30GB+ csv file in python 【发布时间】:2020-02-24 05:40:42 【问题描述】:我有一个大文件 (30GB+) csv,我通过逐块解析文件来计算换行符的数量
使用下面的函数
def yieldblocks(file, size=1024*1024):
while True:
blocks = file.read(size)
if not blocks: break
yield blocks
这样称呼它,
sum(bl.count("\n") for bl in blocks(txtfile))
我可以在一小时内计算换行符(我很惊讶这也是我能得到的最好的)
我的问题是我需要跳过双引号内的新行,因为某些列包含多行内容。
我尝试了以下方法,但它似乎无法正常工作,并且进程退出而没有结果
sum(.5 if re.search('^[^"]*"(?=[^"]*(?:"[^"]*")*[^"]*$).*$', bl) else 1 for bl in yieldblocks(txtfile))
正则表达式是在一行中查找奇数个双引号字符,并且在一个小文件中工作。
我使用的是 2GB RAM,32 位操作系统
注意:我尝试了 CSV 模块,但它比按块计数要慢,我希望我能以某种方式让它工作
【问题讨论】:
如果你使用sum(1 for line in file)
会发生什么?
按块计算换行符要慢得多
不想这么说,但这听起来像是 C 的工作。block.count('\n')
方法可能很快,但它不能处理引用。因此,您必须逐个字节地浏览文件,将您在每个点的引号内还是在引号外制表(并在跨块时记住)。这在 Python 中会非常慢。您可能会发现使用内存映射文件会有所帮助。您也可以使用 pandas.read_csv(非常快),可能通过 StringIO 给它提供块。但是你会很难知道在哪里打破这些块(回到寻找不带引号的行尾的原始问题)。
澄清一下:您实际上感兴趣的是文件中的记录数?
@mkrieger1 是的,请
【参考方案1】:
这可能对您很有效。 pandas.read_csv
通常非常快,但我还没有尝试过分块。
import pandas as pd
reader = pd.read_csv('file.csv', sep=',', chunksize=10000, low_memory=True)
line_count = sum(len(chunk) for chunk in reader)
the documentation 中有更多信息(不多)。
【讨论】:
谢谢马蒂亚斯。我试过这个。文件中存在一个问题,即在某些行中,列标题的数量与实际内容中的列数不匹配,pandas 不喜欢这样并忽略这些行(如果您提供忽略选项。否则它会一起出错) 这将破坏计算记录数的目的 您可能需要尝试看看是否有办法解决这个问题——也许只需要一列而让它忽略其余的列?否则,您可能只需要逐字节处理整个文件。正如@Danny_ds 指出的那样,这项工作可能受 I/O 限制而不是处理器限制,因此您可以在 Python 中逐字节进行。【参考方案2】:最简单最快的方法是使用内存映射并按如下方式遍历字节(伪代码):
bool insidequotes = false
for each byte b:
if b=='"'
insidequotes = not insidequotes // false -> true or true -> false
else if b=='\n' and not insidequotes
increment recordcount
这应该不会比在磁盘上复制文件(甚至只是读取文件)花费的时间更长 - 不确定 Python 中可能的开销。
这也处理字段内的转义引号:
123,test,"24"" monitor",456
【讨论】:
谢谢丹尼。不起作用,因为我使用的是 32 位操作系统,并且无法映射文件 @QVSJ 也许你可以映射 1GB 的块(不确定 Linux 或 Python)。或者如果这不起作用,只需以二进制模式打开文件并循环遍历它。以上是关于在python中计算30GB + csv文件中双引号外的新行数的主要内容,如果未能解决你的问题,请参考以下文章
python:如何读取和处理 18GB 的 csv 文件? [复制]
Python Pandas:标记数据时出错。 C 错误:读取 1GB CSV 文件时字符串中的 EOF 开始
如何使用 python pandas 在本地系统 Jupyter Notebook 中读取两个较大的 5GB csv 文件?如何在本地加入两个数据框进行数据分析?