繁体   English   中英

np.array 的 np.array 的深拷贝

[英]Deep copy of a np.array of np.array

我有一个由不同 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 是最好的方法吗? 有没有我错过的深拷贝功能? 与这个不同大小数组的数组中的每个元素交互的最佳方式是什么?

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)

随意阅读更多关于这里的信息。

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

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

被打了一分钟。 实际上,deepcopy 就是这里的答案。

关于索引的第二个问题:我有一种感觉,在这里使用简单的列表或字典类型的数据结构可能会更好。 np.arrays 主要在每个数组元素属于同一类型时才有意义。 当然,您可以争辩说 array_of_arrays 中的每个元素都是另一个数组,但是将它们收集在一个 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功能。 它是为诸如列表列表之类的东西而设计的,但也适用于数组。 它基本上是在做你用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) 有时这很方便; 其他时候这是一种痛苦(更难迭代)。

只需使用np.array(old_array)应该适用于最新版本的 numpy

array_to_be_copy = np.zeros([3, 3])
deep_copied_array = np.array(array_to_be_copy)

我的 numpy 版本:1.21.1

何时警告可能的贬值:

  1. ..\lib\site-packages\ipykernel_launcher.py:23: DeprecationWarning: elementwise comparison failed; 这将在未来引发错误。

我是这样决定的:

import numpy as np
    import copy
    
    def deepCopyArrayNumPy(arrayNunpy):
        clone = copy.deepcopy(arrayNunpy.tolist())
        return np.array(clone)

一个简单的 np.asarray() 就可以了

np.asarray(array_of_arrays)

供参考: https ://numpy.org/doc/stable/reference/generated/numpy.asarray.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM