高效处理Python中的大型.txt文件

6
我对Python和编程都很陌生,但我想用Python在一个包含大约700万行的制表符分隔的txt文件上运行“滑动窗口”计算。所谓的“滑动窗口”是指它将在大约50000行上运行计算,报告数字,然后向上移动大约10000行,并在另外的50000行上执行相同的计算。如果我在我的数据子集上测试它,我的计算和“滑动窗口”都能正常工作并且运行良好。然而,如果我尝试在整个数据集上运行程序,速度非常慢(现在已经运行了大约40个小时)。这个数学问题非常简单,所以我不认为应该花费这么长时间。
我目前使用csv.DictReader模块读取我的.txt文件。我的代码如下:
file1='/Users/Shared/SmallSetbee.txt'
newfile=open(file1, 'rb')
reader=csv.DictReader((line.replace('\0','') for line in newfile), delimiter="\t")

我认为这是一次性将所有700万行制作成字典,这可能是较大文件减速的原因。
由于我只对一次运行“块”或“窗口”的数据感兴趣,是否有更有效的方法一次只读取指定行,执行计算,然后重复使用新的指定“块”或“窗口”中的指定行?

1
这不会一次性创建所有行的字典。它为每一行创建一个字典。这意味着你发布的代码片段不是你性能问题的原因。也许你可以给我们展示更多的代码? - Steven Rumbalski
1
我怀疑如果你正在对大量类似表格的数据进行计算,你可能需要看一下Pandas:http://pandas.pydata.org/pandas-docs/dev/io.html#iterating-through-files-chunk-by-chunk。你所尝试做的一切可能已经被做过了,而且做得比你好1000倍。 - Iguananaut
您需要在696个“窗口”上运行此计算。单个50k行文件的一个窗口需要多长时间? - Steven Rumbalski
你是否总是将“窗口”向上移动固定大小或固定大小行数的倍数?另外,你使用的Python版本是什么? - martineau
1
对你的代码进行分析并查看它花费时间最多的地方。 - martineau
2个回答

6

collections.deque是一个有序的集合,可以设置最大长度。当你在一端添加一个元素时,另一端会掉落一个元素。这意味着,要在csv上迭代一个“窗口”,只需要不断向deque中添加行,它会自动处理已经完整的行。

dq = collections.deque(maxlen=50000)
with open(...) as csv_file:
    reader = csv.DictReader((line.replace("\0", "") for line in csv_file), delimiter="\t")

    # initial fill
    for _ in range(50000):
        dq.append(reader.next())

    # repeated compute
    try:
        while 1:
            compute(dq)
            for _ in range(10000):
                dq.append(reader.next())
    except StopIteration:
            compute(dq)

1
应该将 try/except 放得更靠近 reader.next(),以避免意外捕获 compute(dq) 中的 StopIteration - jfs

3
不要使用csv.DictReader,而应使用csv.reader。对于每一行创建一个字典需要的时间比创建一个列表更长。此外,通过索引访问列表比通过键访问字典稍微快一些。 我用这两个csv读取器计时迭代300,000行4列的csv文件。csv.DictReader比csv.reader慢七倍。 将此与katrielalex的建议使用collections.deque相结合,你应该会看到一个不错的加速效果。 此外,请分析你的代码以确定你花费大部分时间的位置。

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