function looks like:
def mutate_color(tri):
out = tri.copy()
out[3][np.random.randint(3)] = np.random.randint(256)
return out
one object looks like:
TRI_A = array([array([181, 75]), array([99, 9]), array([53, 15]),
array([18, 5, 19], dtype=uint8)], dtype=object)
<== this is a colored triangle, frist three are coordinates, the last one are RGB value.
But when I pass this (or some object like this to this function):
for example:
TRI_B = mutate_color(TRI_A)
I noticed that both TRI-B and TRI_A are modifed, I mean I use .copy() function, shouldn't TRI_A remain the same as the orignial and only B will be modifed?
Please Help.
CodePudding user response:
The data type of TRI_A
is object
, so the values that are actually stored in the array are the pointers to the various objects (in this case, several different numpy arrays). When the copy()
method creates a new object
array, it only copies the pointers. It does not recursively copy all the Python objects that are pointed to by the numpy array.
This is explained further in the docstring of numpy.copy
. In particular,
Note that np.copy is a shallow copy and will not copy object
elements within arrays. This is mainly important for arrays
containing Python objects. The new array will contain the
same object which may lead to surprises if that object can
be modified (is mutable):
>>> a = np.array([1, 'm', [2, 3, 4]], dtype=object)
>>> b = np.copy(a)
>>> b[2][0] = 10
>>> a
array([1, 'm', list([10, 3, 4])], dtype=object)
To ensure all elements within an ``object`` array are copied,
use `copy.deepcopy`:
>>> import copy
>>> a = np.array([1, 'm', [2, 3, 4]], dtype=object)
>>> c = copy.deepcopy(a)
>>> c[2][0] = 10
>>> c
array([1, 'm', list([10, 3, 4])], dtype=object)
>>> a
array([1, 'm', list([2, 3, 4])], dtype=object)