Numpy Array-Zuordnung mit Kopie

103

Zum Beispiel, wenn wir ein numpyArray Ahaben und ein numpyArray Bmit denselben Elementen wollen.

Was ist der Unterschied zwischen den folgenden (siehe unten) Methoden? Wann wird zusätzlicher Speicher zugewiesen und wann nicht?

  1. B = A
  2. B[:] = A(wie B[:]=A[:]?)
  3. numpy.copy(B, A)
mrgloom
quelle

Antworten:

127

Alle drei Versionen machen unterschiedliche Dinge:

  1. B = A

    Dadurch wird ein neuer Name Ban das bereits benannte vorhandene Objekt gebunden A. Danach beziehen sie sich auf dasselbe Objekt. Wenn Sie also eines an Ort und Stelle ändern, sehen Sie die Änderung auch durch das andere.

  2. B[:] = A(wie B[:]=A[:]?)

    Dadurch werden die Werte aus Aeinem vorhandenen Array kopiert B. Die beiden Arrays müssen dieselbe Form haben, damit dies funktioniert. B[:] = A[:]macht das gleiche ( B = A[:]würde aber eher etwas wie 1 machen).

  3. numpy.copy(B, A)

    Dies ist keine legale Syntax. Du hast es wahrscheinlich gemeint B = numpy.copy(A). Dies ist fast dasselbe wie 2, erstellt jedoch ein neues Array, anstatt das BArray wiederzuverwenden. Wenn es keine anderen Verweise auf den vorherigen BWert gäbe, wäre das Endergebnis dasselbe wie 2, aber es wird vorübergehend mehr Speicher während des Kopierens verbrauchen.

    Oder haben Sie vielleicht gemeint numpy.copyto(B, A), was legal ist und 2 entspricht?

Blckknght
quelle
21
@Mr_and_Mrs_D: Numpy Arrays funktionieren anders als Listen. Durch das Schneiden eines Arrays wird keine Kopie erstellt, sondern lediglich eine neue Ansicht der Daten des vorhandenen Arrays erstellt.
Blckknght
Was ist damit gemeint but B = A[:] would do something more like 1? Demnach ist stackoverflow.com/a/2612815 new_list = old_list[:] auch eine Kopie.
Mrgloom
4
@mrgloom: Numpy Arrays funktionieren anders als Listen, wenn es darum geht, ihren Inhalt zu schneiden und zu kopieren. Ein Array ist eine "Ansicht" eines zugrunde liegenden Speicherblocks, in dem die numerischen Werte gespeichert sind. Wenn Sie ein Slice wie some_array[:]ausführen, wird ein neues Array-Objekt erstellt. Dieses neue Objekt ist jedoch eine Ansicht desselben Speichers wie das ursprüngliche Array, das nicht kopiert wurde. Deshalb habe ich gesagt, es ist eher so B = A. Es braucht nur O(1)Raum und Zeit und nicht die, die O(n)eine echte Kopie benötigen würde.
Blckknght
27
  1. B=A erstellt eine Referenz
  2. B[:]=A macht eine Kopie
  3. numpy.copy(B,A) macht eine Kopie

Die letzten beiden benötigen zusätzlichen Speicher.

Um eine tiefe Kopie zu erstellen, müssen Sie verwenden B = copy.deepcopy(A)

Mailerdaimon
quelle
2
Bezugnehmend auf Ihr zweites Beispiel: B[:] = AErstellt keine tiefe Kopie von Arrays vom Objekttyp, z A = np.array([[1,2,3],[4,5]]); B = np.array([None,None], dtype='O'). Versuchen Sie nun B[:] = A; B[0][0]=99, dies ändert das erste Element in A und B ! Meines Wissens gibt es keinen anderen Weg, um eine tiefe Kopie zu garantieren, selbst eines Numpy-Arrays, alscopy.deepcopy
Rolf Bartstra
11

Dies ist die einzige funktionierende Antwort für mich:

B=numpy.array(A)
Woeitg
quelle