np数组的深度复制

2024-04-26 13:57:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个不同numpy数组的numpy数组,我想对这些数组做一个深度复制。我发现了以下情况:

import numpy as np

pairs = [(2, 3), (3, 4), (4, 5)]
array_of_arrays = np.array([np.arange(a*b).reshape(a,b) for (a, b) in pairs])

a = array_of_arrays[:] # Does not work
b = array_of_arrays[:][:] # Does not work
c = np.array(array_of_arrays, copy=True) # Does not work
d = np.array([np.array(x, copy=True) for x in array_of_arrays])

array_of_arrays[0][0,0] = 100
print a[0][0,0], b[0][0,0], c[0][0,0], d[0][0,0]

d是最好的方法吗?我错过了深度复制功能吗? 在这个由不同大小的数组组成的数组中,与每个元素交互的最佳方式是什么?


Tags: ofinnumpytruefornpnot情况
3条回答
import numpy as np
import copy

pairs = [(2, 3), (3, 4), (4, 5)]
array_of_arrays = np.array([np.arange(a*b).reshape(a,b) for (a, b) in pairs])

a = copy.deepcopy(array_of_arrays)

请随意阅读更多关于这个here的内容。

哦,这里是最简单的测试用例:

a[0][0,0]
print a[0][0,0], array_of_arrays[0][0,0]

被一分钟打败了。事实上,deepcopy就是答案。

关于索引的第二个问题:我觉得在这里使用一个简单的列表或字典类型的数据结构可能会更好。如果每个数组元素都是同一类型的,那么数组就有意义了。当然,您可以争辩说array中的每个元素都是另一个数组,但是将它们收集到一个numpy数组而不是一个简单的列表中有什么好处呢?

list_of_arrays = [np.arange(a*b).reshape(a,b) for (a, b) in pairs]
In [276]: array_of_arrays
Out[276]: 
array([array([[0, 1, 2],
       [3, 4, 5]]),
       array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]]),
       array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]])], dtype=object)

array_of_arraysdtype=object;这意味着数组的每个元素都是指向内存中其他位置的对象的指针。在这种情况下,这些元素是不同大小的数组。

a = array_of_arrays[:]

a是一个新数组,但是array_of_arrays的视图;也就是说,它具有相同的数据缓冲区(在本例中是指针列表)。

b = array_of_arrays[:][:] 

这只是一个视图。第二个[:]作用于第一个的结果。

c = np.array(array_of_arrays, copy=True)

这与array_of_arrays.copy()相同。c有一个新的数据缓冲区,即原始数据的副本

如果我替换c的元素,它不会影响array_of_arrays

c[0] = np.arange(3)

但是如果我修改c的一个元素,它将修改array_of_arrays中的同一个元素,因为它们都指向同一个数组。

同样的事情也适用于列表的嵌套列表。array添加的是view情况。

d = np.array([np.array(x, copy=True) for x in array_of_arrays])

在本例中,您将复制各个元素。正如其他人所指出的,有一个deepcopy函数。它是为列表之类的东西而设计的,但也适用于数组。它基本上就是在递归地处理嵌套树。

通常,对象数组类似于列表嵌套。一些操作跨越对象边界,例如

 array_of_arrays+1

但即便如此

np.array([x+1 for x in array_of_arrays])

与列表相比,对象数组添加的一件事是像reshape这样的操作。array_of_arrays.reshape(3,1)使其成为2d;如果它有4个元素,则可以执行array_of_arrays.reshape(2,2)。有时候这很方便;有时候这很痛苦(很难重复)。

相关问题 更多 >