numpy的asarray()是否引用原始列表?
我有一个很长的列表,里面又包含了很多列表。我正在用numpy.asarray()把它转换成一个numpy数组。请问,在得到这个数组之后,我可以安全地删除原来的列表吗?这样做会不会影响到新创建的numpy数组?
3 个回答
1
是的,如果你的输入数据是一个 list
,那么删除它是安全的。根据文档的说明,只有当输入数据已经是一个 ndarray 时,才不会进行复制。
2
数据被复制过来是因为numpy数组会存储自己的一份数据副本,正如Bas Swinckels所描述的那样。你也可以自己测试一下这个情况。虽然一个非常小的列表可能也能说明这个问题,但下面这个巨大的数据集可能会更清楚地让你明白这一点;)
import numpy as np
list_data = range(1000000000) # note, this will probably take a long time
# This will also take a long time
# because it is copying the data in memory
array_data = np.asarray(list_data)
# even this will probably take a while
del list_data
# But you still have the data even after deleting the list
print(array_data[1000])
3
我很确定数据是不会共享的,所以你可以放心地删除那些列表。你最开始的 matrix
是一个嵌套的Python对象结构,里面的数字也是Python对象,它们可以在内存中的任何地方。Numpy数组也是一个对象,但它更像是一个包含数据维度和类型的头部,同时指向一块连续的数据区域,所有的数字都尽可能紧凑地存放在一起,像是“原始数字”。这两种不同的方式是无法共享数据的,所以当你创建Numpy数组时,数据应该是被复制的。举个例子:
In [1]: m = [[1,2,3],[4,5,6],[7,8,9]]
In [2]: import numpy as np
In [3]: M = np.array(m)
In [4]: M[1,1] = 55
In [5]: M
Out[5]:
array([[ 1, 2, 3],
[ 4, 55, 6],
[ 7, 8, 9]])
In [6]: m
Out[6]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]] # original is not modified!
需要注意的是,Numpy数组之间可以共享数据,比如当你对一个数组进行切片时。这被称为“视图”,所以如果你在这个子集里修改数据,原始数组中的数据也会跟着改变:
In [18]: P = M[1:, 1:]
In [19]: P[1,1] = 666
In [20]: P
Out[20]:
array([[ 55, 6],
[ 8, 666]])
In [21]: M
Out[21]:
array([[ 1, 2, 3],
[ 4, 55, 6],
[ 7, 8, 666]]) # original is also modified!