Numpy copy method does not create a deep copy?

Asked

Viewed 36 times

1

I’m taking a look at Numpy’s arrays and saw that method copy should make a deep copy array. When I create an array of strings or numerical values this seems to be true. However, when I create an array containing an instance of a class I created, the method copy copies only the reference (Shallow copy). For example:

import numpy as np

class Teste:
   def __init(self, var1, var2):
      self.var1 = var1
      self.var2 = var2

   def __copy__(self):
      return Teste(self.var1, self.var2)

t = Teste(20, 30)

arr1 = np.array([t])
arr2 = arr1.copy()

id(arr1[0) == id(arr2[0]) == id(t)

The comparison on the last line of code returns True, which indicates that both arr1 how much arr2 keep the same reference for the object t. My expectation was that the method copy create a new object Teste.

I get this behavior when I use the method deepcopy module copy. So I was wondering if I’m using the method copy of the array correctly and if this is really the expected behavior of this method.

1 answer

1


The expected behavior is the same.

To documentation cites that ndarray.copy is similar to numpy.copy, and the documentation of numpy.copy says the following:

np.copy is a Shallow copy and will not copy Object Elements Within arrays

The same documentation recommends using copy.deepcopy if you want objects to be copied as well. In this case, you don’t even need the method __copy__:

import numpy as np

class Teste:
    def __init__(self, var1, var2):
        self.var1 = var1
        self.var2 = var2

t = Teste(20, 30)

arr1 = np.array([t])
arr2 = arr1.copy()

# imprimindo o id antes (são todos iguais)
print(id(t))
print(id(arr1[0]))
print(id(arr2[0]), arr2[0].var1, arr2[0].var2)

# usando deepcopy
from copy import deepcopy
arr2 = deepcopy(arr1)
# o id depois mudou, mas o conteúdo dos campos foi copiado
print(id(arr2[0]), arr2[0].var1, arr2[0].var2)

Remember that you should only create the methods __copy__ and __deepcopy__ if you want your class to use a specific implementation to create the copies, otherwise it is not necessary to create them. From documentation:

In order for a class to define its Own copy implementation, it can define special methods __copy__() and __deepcopy__()

But in your case it doesn’t seem necessary, since you want to copy exactly all fields, without any additional logic.

  • Thank you for your reply. I’m following Deitel’s book, Python for Programmers, and in section 7.12 it says that the ndarray.copy method does a deep copy of the array. Apparently the author gave a big slip. Again, thank you very much.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.