python加载的内存多于文件的实际大小

时间:2016-04-06 19:51:06

标签: python memory large-files

我有一个大约28Gb的3列文件。我想用python阅读它并将其内容放在3D元组列表中。以下是我使用的代码:

f = open(filename)
col1 = [float(l.split()[0]) for l in f]
f.seek(0)
col2 = [float(l.split()[1]) for l in f]
f.seek(0)
col3 = [float(l.split()[2]) for l in f]
f.close()
rowFormat = [col1,col2,col3]
tupleFormat = zip(*rowFormat)
for ele in tupleFormat: 
        ### do something with ele

没有'休息' for循环中的命令,意味着我实际上读取了文件的整个内容。当脚本运行时,我注意到了“htop”的问题。命令它需要156G的虚拟内存(VIRT列)和几乎相同的驻留内存(RES列)。为什么我的脚本使用156G而文件大小只有28G?

3 个答案:

答案 0 :(得分:2)

Python对象有很多被无意中听到,例如,对象的引用计数和其他东西。这意味着Python float超过8个字节。在我的32位Python版本上,它是

>>> import sys
>>> print(sys.getsizeof(float(0))
16

列表有自己的开销,然后每个元素需要4个字节来存储对该对象的引用。因此,列表中的100个浮点数实际上占用了

的大小
>>> a = map(float, range(100))
>>> sys.getsizeof(a) + sys.getsizeof(a[0])*len(a)
2036

现在,一个numpy数组是不同的。它有一点开销,但引擎盖下的原始数据存储在C中。

>>> import numpy as np
>>> b = np.array(a)
>>> sys.getsizeof(b)
848
>>> b.itemsize    # number of bytes per element
8

因此Python浮点数需要20个字节,而numpy需要8个字节。并64bit Python versions require even more

实际上,如果你必须在内存中加载大量数据,那么numpy就是一种方式。看一下加载数据的方式,我假设它是文本格式,每行有3个浮点数,由任意数量的空格分隔。在这种情况下,您可以使用numpy.genfromtxt()

data = np.genfromtxt(fname, autostrip=True)

您还可以查找更多选项here,例如mmap,但我不太了解它是否适​​合您。

答案 1 :(得分:0)

你需要使用生成器懒洋洋地逐行阅读。试试这个:

col1 = []
col2 = []
col3 = []

rowFormat = [col1, col2, col3]

with open('test', 'r') as f:
    for line in f:
        parts = line.split()
        col1.append(float(parts[0]))
        col2.append(float(parts[1]))
        col3.append(float(parts[2]))
        # if possible do something here to start seeing results immediately

tupleFormat = zip(*rowFormat)
for ele in tupleFormat:
    ### do something with ele

您可以在for循环中添加逻辑,这样就不必等待整个过程完成。

答案 2 :(得分:0)

你可以通过存储每个元组来获得吗?即你在文件中阅读时会“做某事”吗?如果是这样的话......试试这个:

#!/usr/bin/env python
import fileinput
for line in fileinput.FileInput('test.dat'):
    ele = tuple((float(x) for x in line.strip().split()))
    # Replace 'print' with your "do something".
    # Note that ele is now a generator, not a tuple.  Wrap it in
    # ele = tuple(ele) to get a tuple instead if you need it.
    print ele

如果没有,也许您可​​以通过选择列格式元组格式列表来节省一些内存,但不能同时保存一些内存....

#!/usr/bin/env python
import fileinput
elements = []
for line in fileinput.FileInput('test.dat'):
    elements.append(tuple((float(x) for x in line.strip().split())))

for ele in elements:
   # do something