简体   繁体   中英

Deep copy of a np.array of np.array

I have a numpy array of different numpy arrays and I want to make a deep copy of the arrays. I found out the following:

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]

Is d the best way to do this? Is there a deep copy function I missed? And what is the best way to interact with each element in this array of different sized arrays?

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)

Feel free to read up more about this here .

Oh, here is simplest test case:

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

Beaten by one minute. Indeed, deepcopy is the answer here.

To your second question abut indexing: I have a feeling that you may be better off with a simple list or a dictionary-type data structure here. np.arrays make sense primarily if each array element is of the same type. Of course you can argue that each element in array_of_arrays is another array, but what is the benefit of having them collected in a numpy array instead of a simple list?

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_arrays is dtype=object ; that means each element of the array is a pointer to an object else where in memory. In this case those elements are arrays of different sizes.

a = array_of_arrays[:]

a is a new array, but a view of array_of_arrays ; that is, it has the same data buffer (which in this case is list of pointers).

b = array_of_arrays[:][:] 

this is just a view of a view. The second [:] acts on the result of the first.

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

This is the same as array_of_arrays.copy() . c has a new data buffer, a copy of the originals

If I replace an element of c , it will not affect array_of_arrays :

c[0] = np.arange(3)

But if I modify an element of c , it will modify the same element in array_of_arrays - because they both point to the same array.

The same sort of thing applies to nested lists of lists. What array adds is the view case.

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

In this case you are making copies of the individual elements. As others noted there is a deepcopy function. It was designed for things like lists of lists, but works on arrays as well. It is basically doing what you do with d ; recursively working down the nesting tree.

In general, an object array is like list nesting. A few operations cross the object boundary, eg

 array_of_arrays+1

but even this effectively is

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

One thing that a object array adds, compared to a list, is operations like reshape . array_of_arrays.reshape(3,1) makes it 2d; if it had 4 elements you could do array_of_arrays.reshape(2,2) . Some times that's handy; other times it's a pain (it's harder to iterate).

Just use np.array(old_array) should work for the latest version of numpy

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

My numpy version: 1.21.1

When to warn of possible depreciation:

  1. ..\lib\site-packages\ipykernel_launcher.py:23: DeprecationWarning: elementwise comparison failed; this will raise an error in the future.

I decided like that:

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

A simple np.asarray() would do it

np.asarray(array_of_arrays)

For reference: https://numpy.org/doc/stable/reference/generated/numpy.asarray.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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