如果我在内存中有一个庞大的列表列表并希望将其转换为数组,那么天真的方法是否会导致python复制所有数据,占用内存空间的两倍?我应该转换列表列表,按矢量而不是弹出?
# for instance
list_of_lists = [[...], ..., [...]]
arr = np.array(list_of_lists)
编辑:
是否更好的是创建一个已知大小的空数组,然后逐步填充它,从而完全避免list_of_lists
对象?这可以通过简单的some_array[i] = some_list_of_float_values
来完成吗?
答案 0 :(得分:1)
我只是把这里的人放在这里,因为评论有点长。
您是否阅读过array
的numpy文档?
numpy.array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0)
"""
...
copy : bool, optional
If true (default), then the object is copied. Otherwise, a copy will
only be made if __array__ returns a copy, if obj is a nested sequence,
or if a copy is needed to satisfy any of the other requirements (dtype,
order, etc.).
...
"""
当您说在创建numpy
数组时,您不想复制原始数组的数据时,您希望最终会使用哪种数据结构?< / p>
使用numpy
可以获得很多速度,因为创建的C数组在内存中是连续的。 python中的数组只是一个指向对象的指针数组,因此每次都必须去查找对象 - numpy
中的情况并非如此,因为它不是用python编写的
如果你想让numpy
数组引用你的2D数组中的python数组,那么你将失去性能提升。
如果你np.array(my_2D_python_array, copy=False)
我不知道它实际会产生什么,但你可以自己轻松地测试它。查看数组的形状,看看它所包含的物体类型。
如果你希望numpy数组是连续的,那么你需要分配所需的所有内存(如果它和你建议的一样大) ,听起来似乎很难找到足够大的连续部分。
很抱歉这是非常漫无边际的,只是一个评论。您正在查看的实际阵列有多大?
这是一个小样本程序的CPU使用率和内存使用情况的图表:
from __future__ import division
#Make a large python 2D array
N, M = 10000, 18750
print "%i x %i = %i doubles = %f GB" % (N, M, N * M, N*M*8/10**9)
#grab pid to moniter memory and cpu usage
import os
pid = os.getpid()
os.system("python moniter.py -p " + str(pid) + " &")
print "building python matrix"
large_2d_array = [[n + m*M for n in range(N)] for m in range(M)]
import numpy
from datetime import datetime
print datetime.now(), "creating numpy array with copy"
np1 = numpy.array(large_2d_array, copy=True)
print datetime.now(), "deleting array"
del(np1)
print datetime.now(), "creating numpy array with copy"
np1 = numpy.array(large_2d_array, copy=False)
print datetime.now(), "deleting array"
del(np1)
1,2和3是每个矩阵完成创建的点。请注意,本机python数组比numpy数组占用更多内存 - 每个python对象都有自己的开销,列表是对象列表。对于numpy数组,情况并非如此,因此它要小得多。
另请注意,在python对象上使用副本无效 - 始终会创建新数据。你可以通过创建一个numpy数组的python对象来解决这个问题(使用dtype=object
),但我不会建议它。