当我使用numpy.loadtxt加载数组时,它似乎占用了太多内存。 E.g。
a = numpy.zeros(int(1e6))
导致内存增加约8MB(使用htop,或仅8bytes * 1百万\大约8MB)。另一方面,如果我保存然后加载此数组
numpy.savetxt('a.csv', a)
b = numpy.loadtxt('a.csv')
我的内存使用量增加了大约100MB!我再次用htop观察到了这一点。这是在iPython shell中观察到的,也是在使用Pdb ++踩过代码时观察到的。
知道这里发生了什么吗?
在阅读了jozzas的回答之后,我意识到如果我提前知道数组大小,那么如果说'a'是mxn数组,那么有更多内存有效的方法:
b = numpy.zeros((m,n))
with open('a.csv', 'r') as f:
reader = csv.reader(f)
for i, row in enumerate(reader):
b[i,:] = numpy.array(row)
答案 0 :(得分:5)
将此浮点数组保存到文本文件会创建一个24M文本文件。当你重新加载它时,numpy逐行遍历文件,解析文本并重新创建对象。
我希望在这段时间内内存使用量会增加,因为numpy不知道结果数组在到达文件末尾之前需要多大,所以我希望至少有24M +使用8M +其他临时内存。
这是numpy代码的相关位,来自/lib/npyio.py
:
# Parse each line, including the first
for i, line in enumerate(itertools.chain([first_line], fh)):
vals = split_line(line)
if len(vals) == 0:
continue
if usecols:
vals = [vals[i] for i in usecols]
# Convert each value according to its column and store
items = [conv(val) for (conv, val) in zip(converters, vals)]
# Then pack it according to the dtype's nesting
items = pack_items(items, packing)
X.append(items)
#...A bit further on
X = np.array(X, dtype)
这个额外的内存使用不应该是一个问题,因为这只是python的工作方式 - 而你的python进程似乎使用100M的内存,在内部它保持知道哪些项不再使用,并将重新 - 使用那个记忆。例如,如果您要在一个程序中重新运行此保存加载过程(保存,加载,保存,加载),则内存使用量不会增加到200M。
答案 1 :(得分:0)
这就是我最终要解决的问题。即使您不提前知道形状,它也可以工作。这将执行首先转换为浮点的转换,然后 then 合并数组(与@JohnLyon's answer相对,后者将字符串的数组合并然后转换为浮点)。这对我来说使用的内存减少了一个数量级,尽管可能会慢一些。但是,我实际上没有使用np.loadtxt
所需的内存,因此,如果您没有足够的内存,那会更好:
def numpy_loadtxt_memory_friendly(the_file, max_bytes = 1000000, **loadtxt_kwargs):
numpy_arrs = []
with open(the_file, 'rb') as f:
i = 0
while True:
print(i)
some_lines = f.readlines(max_bytes)
if len(some_lines) == 0:
break
vec = np.loadtxt(some_lines, **loadtxt_kwargs)
if len(vec.shape) < 2:
vec = vec.reshape(1,-1)
numpy_arrs.append(vec)
i+=len(some_lines)
return np.concatenate(numpy_arrs, axis=0)