以块的形式处理大文件

时间:2013-07-25 19:01:23

标签: python

我有一个大文件,每行有两个数字,按第二列排序。我在第一列上制作了一个列表字典。

我的代码看起来像

from collections import defaultdict
d = defaultdict(list)
for line in fin.readline():
    vals = line.split()
    d[vals[0]].append(vals[1])
process(d)

但输入文件太大太大,因此d不适合内存。

为了解决这个问题,我原则上可以一次读取文件的块,但我需要在块之间进行重叠,以便process(d)不会遗漏任何内容。

在伪代码中,我可以执行以下操作。

  1. 阅读100行创建字典d
  2. 处理字典d
  3. 删除d中距离目前为止最大值不超过10的所有内容。
  4. 重复但确保我们d中的任何时候都没有超过100行的数据。
  5. 在python中有一个很好的方法吗?

    更新。问题的详细信息。我将在读取第二个文件对时使用d,如果取决于与d中第一个值相关的列表中有多少个值,我将输出该对。第二个文件也按第二列排序。

    虚假数据。 假设我们可以将5行数据放入内存中,我们需要将值重叠为5。

    1 1
    2 1
    1 6
    7 6
    1 16
    

    所以现在d是{1:[1,6,16],2:[1],7:[6]}。

    对于下一个块,我们只需要保留最后一个值(如16-6> 5)。所以我们要设置

    d为{1:[16]}并继续阅读下一行 4 行。

3 个答案:

答案 0 :(得分:2)

您是否尝过Pandas library,特别是将数据读入DataFrame,然后在第一列使用groupby

Pandas会让您在整个数据中有效地进行大量批量操作,如果您愿意,可以read it in lazily

答案 1 :(得分:0)

除非文件发生异常,否则你不需要默认的dict,但你没有提到它是什么。相反,使用一个列表来保持数据的顺序排列,这样就可以使用适当的切片处理它:

d = []
for line in fin.readline():
    vals = line.split()
    d.append(vals)
    if not len(d)%100:
        process(d)
        d = d[90:]
process(d)

答案 2 :(得分:0)

你可以这样做:

n_process = 100
n_overlap = 10
data_chunk = []
for line in fin.readline():
    vals = line.split()
    data_chunk.append(vals)
    if len(data_chunk) == n_process:
        process(data_chunk)
        data_chunk = data_chunk[-n_overlap:]

使用字典时,如果数据样本中存在第一列中多次出现的数字,则可以覆盖数据。另请注意,您需要使用OrderedDict,因为dict在python中没有订单。但是,在我看来,OrderedDict在大多数情况下是代码设计错误的标志。

顺便说一句:我们仍然不知道你为什么要这样做......