Python如何读取巨大的二进制文件(> 25GB)?

时间:2017-05-27 17:48:25

标签: python parallel-processing binaryfiles readfile bigdata

我有N-body模拟数据,必须在python中读取该文件。

它的大小超过25GB,因此缺少内存无法使用file.read()。

所以我写了这样的代码

with open("fullFoF_merger.cbin.z0.Run1", "rb") as mergertree:
    def param(data):
        result = {"nowhid":data[0], "nexthid":data[2],"zi":data[10], 
                  "zip1":data[11], "F":data[4], "mass":data[9], 
                  "dlnM":data[5],"dM":data[12], "dlnJ":data[6],"dJ":data[13],
                  "dlnspin": data[7], "spin":data[8],
                  "G":data[14], "overden":data[15]}
        return result

    num = 0

    while 1:
        num +=1

        binary_data = mergertree.read(4)

        if not binary_data : break

        n_max = struct.unpack('I', binary_data)


        binary_data = mergertree.read(64*n_max[0])

        Halo = [None]*n_max[0]


        for i in range(1,n_max[0]+1):
            data = struct.unpack("4i12f", binary_data[64*(i-1):64*(i)])
            Halo[i-1] = param(data)

        MergerQ = []+Halo


print(MergerQ)

print(num)

print("\n Run time \n --- %d seconds ---" %(time.time()-start_time))

在此过程中while循环在此代码中计算45470522次。但是当我在python中打印MergerQ时,它只显示一个像这样的字典数据

[{'nowhid': 53724, 'nexthid': 21912952, 'zi': 0.019874930381774902, 'zip1': -1.6510486602783203e-05, 'F': inf, 'mass': 67336740864.0, 'dlnM': 0.0, 'dM': 0.0, 'dlnJ': 0.1983184665441513, 'dJ': 8463334768640.0, 'dlnspin': 0.19668935239315033, 'spin': 0.012752866372466087, 'G': inf, 'overden': 1.0068886280059814}]

我认为这是由于python的变量缺乏内存或内存限制造成的。

我该如何解决这个问题?

有没有办法读取整个数据并保存在python变量中?

并行计算可以解决这个代码吗?

我会等你的评论。谢谢。

1 个答案:

答案 0 :(得分:0)

这一行是你的问题:

CREATE OR REPLACE TRIGGER radnici_strucna_sprema
 BEFORE INSERT OR UPDATE ON radnici
FOR EACH ROW
DECLARE
  v_stru VARCHAR2(50);
BEGIN
  v_stru := :NEW.strucna_sprema;
  IF v_ss = 'osnovno' THEN
    :NEW.strucna_sprema := v_stru;
  ELSIF v_ss = 'srednje' THEN
    :NEW.strucna_sprema := v_stru;
  ELSIF v_ss = 'vise' THEN
    :NEW.strucna_sprema := v_stru;
  ELSIF grade = 'visoko' THEN
    :NEW.strucna_sprema := v_stru;
  ELSE
    RAISE_APPLICATION_ERROR(NUM => -20002, 
            MSG => 'Forma strucne spreme nije odgovarajuca!');
  END IF;
END;

您清除MergerQ = []+Halo ,将其置于循环之外:

MergerQ

但如果文件太大,不要指望存储整个内存所需的内存量,你需要大量内存和大量时间。 < / p>

修改

你很有可能成功运行你的代码而不需要太多的物理RAM,因为你的操作系统可能会将它存储在硬盘中,并在需要时获取它,但这将大量增加运行时间。

尝试运行此代码段并查看会发生什么(预警:如果您将此设备运行太长时间,您的计算机将无法响应,并且很可能需要进行物理重置

num = 0
MergerQ = []

while 1:
    ...
    MergerQ += Halo

期待您的脚本做出类似的反应。