Asignación de matrices Numpy con copia

103

Por ejemplo, si tenemos una numpymatriz Ay queremos una numpymatriz Bcon los mismos elementos.

¿Cuál es la diferencia entre los siguientes métodos (ver más abajo)? ¿Cuándo se asigna memoria adicional y cuándo no?

  1. B = A
  2. B[:] = A(igual que B[:]=A[:]?)
  3. numpy.copy(B, A)
mrgloom
fuente

Respuestas:

127

Las tres versiones hacen cosas diferentes:

  1. B = A

    Esto une un nuevo nombre Bal objeto existente ya nombrado A. Luego se refieren al mismo objeto, por lo que si modifica uno en su lugar, verá el cambio a través del otro también.

  2. B[:] = A(igual que B[:]=A[:]?)

    Esto copia los valores de Auna matriz existente B. Las dos matrices deben tener la misma forma para que esto funcione. B[:] = A[:]hace lo mismo (pero B = A[:]haría algo más como 1).

  3. numpy.copy(B, A)

    Esta no es una sintaxis legal. Probablemente quisiste decir B = numpy.copy(A). Es casi lo mismo que 2, pero crea una nueva matriz, en lugar de reutilizar la Bmatriz. Si no hubiera otras referencias al Bvalor anterior , el resultado final sería el mismo que 2, pero usará más memoria temporalmente durante la copia.

    ¿O quizás quisiste decir numpy.copyto(B, A), que es legal y es equivalente a 2?

Blckknght
fuente
21
@Mr_and_Mrs_D: Los arreglos Numpy funcionan de manera diferente a las listas. Cortar una matriz no hace una copia, solo crea una nueva vista de los datos de la matriz existente.
Blckknght
¿Qué se entiende por but B = A[:] would do something more like 1? Según esto, stackoverflow.com/a/2612815 new_list = old_list[:] también es una copia.
mrgloom
4
@mrgloom: las matrices Numpy funcionan de manera diferente a las listas cuando se trata de cortar y copiar su contenido. Una matriz es una "vista" de un bloque de memoria subyacente donde se almacenan los valores numéricos. Hacer un corte como some_array[:]creará un nuevo objeto de matriz, pero ese nuevo objeto será una vista de la misma memoria que la matriz original, que no se habrá copiado. Por eso dije que es más parecido B = A. Solo toma O(1)espacio y tiempo, en lugar de la cantidad O(n)de cada uno que necesitaría una copia real.
Blckknght
27
  1. B=A crea una referencia
  2. B[:]=A hace una copia
  3. numpy.copy(B,A) hace una copia

los dos últimos necesitan memoria adicional.

Para hacer una copia profunda necesitas usar B = copy.deepcopy(A)

Mailerdaimon
fuente
2
Refiriéndose a su segundo ejemplo: B[:] = Aqué no hacer una copia profunda de matrices de tipo de objeto, por ejemplo A = np.array([[1,2,3],[4,5]]); B = np.array([None,None], dtype='O'). Ahora inténtelo B[:] = A; B[0][0]=99, ¡esto cambiará el primer elemento tanto en A como en B ! Que yo sepa, no hay otra forma de garantizar una copia profunda, incluso de una matriz numérica, quecopy.deepcopy
Rolf Bartstra
11

Esta es la única respuesta que funciona para mí:

B=numpy.array(A)
Woeitg
fuente