index - Python: Numpy__deepcopy__ TypeError
numpy array zeros (3)
El método especial __deepcopy__
toma una memo
arg. Puedes pasar un dict vacío para esto:
foo = myArray.__deepcopy__({})
Intento usar deepcopy en un ndarray, y la línea se ve así:
foo = myArray.__deepcopy__()
Me estoy poniendo:
TypeError: function takes exactly 1 argument (0 given)
Necesito una copia profunda, y no puedo importar la copia.
El módulo de copy
contiene la documentación para __deepcopy__
, y está bastante claro cuál debería ser el argumento:
Para que una clase defina su propia implementación de copia, puede definir métodos especiales
__copy__()
y__deepcopy__()
. El primero es llamado para implementar la operación de copia superficial; no se pasan argumentos adicionales El último es llamado para implementar la operación de copia profunda; se pasa un argumento, el diccionario de notas.
Pero si no está implementando una clase personalizada de copia profunda, generalmente no necesita preocuparse por esto, simplemente use copy.deepcopy
:
from copy import deepcopy
import numpy as np
arr = np.random.random((100, 100))
deepcopy(arr)
Se encargará del memo
sin su intervención. Nota: la mayoría de los __*__
están diseñados de esa manera, por lo general, no y no debe llamarlos directamente. Así que como usas x in y
lugar de y.__contains__(x)
normalmente usas copy.deepcopy(x)
lugar de x.__deepcopy__(dict())
.
El código relevante en la copy
es:
def deepcopy(x, memo=None, _nil=[]):
"""Deep copy operation on arbitrary Python objects.
See the module''s __doc__ string for more info.
"""
if memo is None:
memo = {}
....
copier = getattr(x, "__deepcopy__", None)
if copier:
y = copier(memo)
...
# If is its own copy, don''t memoize.
if y is not x:
memo[d] = y
_keep_alive(x, memo) # Make sure x lives at least as long as d
return y
Así que memo
es un diccionario de memoize
, al menos cuando se usa "correctamente"
Entonces, si paso un diccionario como memo
, eso cambia eso:
In [160]: dd={}
In [161]: A2=copy.deepcopy(A,memo=dd)
In [162]: dd
Out[162]:
{2814755008: array([[[0, 1, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 1],
[0, 0, 0, 1, 0, 1],
[1, 0, 0, 0, 1, 0]],
[[0, 0, 1, 0, 0, 0],
[0, 0, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0]]]), 2814808588: [array([[[0, 1, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 1],
[0, 0, 0, 1, 0, 1],
[1, 0, 0, 0, 1, 0]],
[[0, 0, 1, 0, 0, 0],
[0, 0, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0]]])]}
In [163]: id(A)
Out[163]: 2814755008
In [167]: id(dd[id(A)])
Out[167]: 2814568472
In [168]: id(A2)
Out[168]: 2814568472
La memo
guarda un registro de la copia. No sé cuál es el segundo artículo.
Y si solicito otra copia profunda con la misma nota, da la matriz memorada en lugar de una nueva copia.
In [173]: A3=copy.deepcopy(A,memo=dd)
In [174]: id(A2)
Out[174]: 2814568472
In [175]: id(A3)
Out[175]: 2814568472
Si una matriz es objeto dtype, la deepcopy
puede marcar la diferencia. La nota ciertamente se ve diferente.