【发布时间】:2014-07-11 15:48:58
【问题描述】:
我正在尝试运行一些使用 Python 分析数据的脚本,但我很快就对它占用的 RAM 空间感到惊讶:
我的脚本从文件中读取两列整数。它通过以下方式导入它:
import numpy as N
from sys import argv
infile = argv[1]
data = N.loadtxt(infile,dtype=N.int32) //infile is the input file
对于一个包含近 800 万行的文件,它需要大约 1.5 Gb 的内存(在这个阶段它所做的只是导入数据)。
我尝试在其上运行内存分析器,结果如下:
Line # Mem 使用增量行内容
5 17.664 MiB 0.000 MiB @profile
6 def func():
7 17.668 MiB 0.004 MiB infile = argv[1]
8 258.980 MiB 241.312 MiB data = N.loadtxt(infile,dtype=N.int32)
所以 250Mb 的数据,与内存中的 1.5Gb 相差甚远(什么占用了这么多空间?)
当我尝试使用 int16 而不是 int32 将其除以 2 时:
Line # Mem 使用增量行内容
5 17.664 MiB 0.000 MiB @profile
6 def func():
7 17.668 MiB 0.004 MiB infile = argv[1]
8 229.387 MiB 211.719 MiB data = N.loadtxt(infile,dtype=N.int16)
但我只存了十分之一,怎么会?
我不太了解内存占用,但这正常吗?
另外,我在 C++ 中编写了相同的代码,将数据存储在 vector<int> 对象中,它只占用 120Mb 的 RAM。
在我看来,Python 在处理内存方面似乎占了很大的比重,它在做什么会增加数据的权重?是不是和 Numpy 关系更密切?
受以下答案的启发,我现在通过以下方式导入我的数据:
infile = argv[1]
output = commands.getoutput("wc -l " + infile) #I'm using the wc linux command to read the number of lines in my file and so how much memory allocation do I need
n_lines = int(output.split(" ")[0]) #the first int is the number of lines
data = N.empty((n_lines,2),dtype=N.int16) #allocating
datafile = open(infile)
for count,line in enumerate(datafile): #reading line by line
data[count] = line.split(" ") #filling the array
它对多个文件的工作方式也非常相似:
infiles = argv[1:]
n_lines = sum(int(commands.getoutput("wc -l " + infile).split(" ")[0]) for infile in infiles)
i = 0
data = N.empty((n_lines,2),dtype=N.int16)
for infile in infiles:
datafile = open(infile)
for line in datafile:
data[i] = line.split(" ")
i+=1
罪魁祸首似乎是numpy.loadtxt,删除它后我的脚本现在不需要大量内存,甚至运行速度快了 2-3 倍 =)
【问题讨论】: