我有一个不同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]
这是最好的方法吗?我错过了深层复制功能吗? 与这个不同大小的数组数组中的每个元素进行交互的最佳方法是什么?
答案 0 :(得分:12)
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]
答案 1 :(得分:4)
被打了一分钟。实际上,深度复制是这里的答案。
关于索引的第二个问题:我觉得你可能会在这里使用简单的列表或字典类型的数据结构。 np.arrays主要是有意义的,如果每个数组元素是相同的类型。当然你可以争辩说array_of_arrays中的每个元素都是另一个数组,但是将它们收集在一个numpy数组而不是一个简单的列表中有什么好处呢?
list_of_arrays = [np.arange(a*b).reshape(a,b) for (a, b) in pairs]
答案 2 :(得分:2)
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_arrays
是dtype=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
功能。它是为列表列表之类的东西设计的,但也适用于数组。它基本上是用d
做的;以递归方式处理嵌套树。
通常,对象数组就像列表嵌套一样。一些操作穿过对象边界,例如
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)
。有时候很方便;其他时候它很痛苦(迭代很难)。
答案 3 :(得分:0)
何时警告可能的折旧:
我是这样决定的:
import numpy as np import copy def deepCopyArrayNumPy(arrayNunpy): clone = copy.deepcopy(arrayNunpy.tolist()) return np.array(clone)
答案 4 :(得分:0)
只需使用 np.array(old_array)
应该适用于最新版本的 numpy
array_to_be_copy = np.zeros([3, 3])
deep_copied_array = np.array(array_to_bo_copy)
我的 numpy 版本:1.21.1
答案 5 :(得分:-1)
一个简单的 np.asarray() 就可以了
np.asarray(array_of_arrays)
供参考:https://numpy.org/doc/stable/reference/generated/numpy.asarray.html