如何从大量数据中有效地构造numpy数组?

时间:2015-02-25 12:18:10

标签: python arrays numpy

如果我在内存中有一个庞大的列表列表并希望将其转换为数组,那么天真的方法是否会导致python复制所有数据,占用内存空间的两倍?我应该转换列表列表,按矢量而不是弹出?

# for instance
list_of_lists = [[...], ..., [...]]
arr = np.array(list_of_lists)

编辑: 是否更好的是创建一个已知大小的空数组,然后逐步填充它,从而完全避免list_of_lists对象?这可以通过简单的some_array[i] = some_list_of_float_values来完成吗?

1 个答案:

答案 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)

enter image description here

1,2和3是每个矩阵完成创建的点。请注意,本机python数组比numpy数组占用更多内存 - 每个python对象都有自己的开销,列表是对象列表。对于numpy数组,情况并非如此,因此它要小得多。

另请注意,在python对象上使用副本无效 - 始终会创建新数据。你可以通过创建一个numpy数组的python对象来解决这个问题(使用dtype=object),但我不会建议它。