numpy的asarray()是否引用原始列表?

3 投票
3 回答
1932 浏览
提问于 2025-04-20 08:05

我有一个很长的列表,里面又包含了很多列表。我正在用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!

撰写回答