Blick auf das Array, und seine Struktur zuerst verstehen:
In [139]: A1
Out[139]: array([[[[1, 1], 2, 3]]], dtype=object)
In [140]: A1.shape
Out[140]: (1, 1, 3)
Es ist ein dtype=object
Array; das sind die Elemente sind Objektzeiger, keine Zahlen. Auch es ist 3d, mit 3 Elementen.
In [142]: A1[0,0]
Out[142]: array([[1, 1], 2, 3], dtype=object)
Da es ein Array ist, ist besser als A1[0,0]
A1[0][0]
. Funktional gleich, aber klarer. A1[0,0,:]
ist noch besser. Wie auch immer, auf dieser Ebene haben wir immer noch ein Array mit der Form (3,)
, d.h. 1d mit 3 Elementen.
In [143]: A1[0,0,0]
Out[143]: [1, 1]
In [144]: A1[0,0,2]
Out[144]: 3
Jetzt bekommen wir eine Liste und Zahlen, die einzelnen Elemente A1
. Die Liste ist änderbar, die Nummer nicht.
Wir können das dritte Element ändern (eine Zahl) in einen String:
In [148]: A1[0,0,2]='xy'
Um ein Element des ersten Elements zu ändern, eine Liste, ich habe die gemischte Indizierung verwenden, keine 4-Level-Array Indizierung.
In [149]: A1[0,0,0,0]
...
IndexError: too many indices for array
In [150]: A1[0,0,0][0]='yy'
In [151]: A1
Out[151]: array([[[['yy', 1], 2, 'xy']]], dtype=object)
A1
ist immer noch eine 3D-Objektarray; Wir haben nur ein paar Elemente geändert. Die 'xy' Änderung unterscheidet sich von der 'yy' Änderung. Einer hat das Array geändert, der andere ein Listenelement des Arrays.
A2=A1.copy()
erstellt ein neues Array mit Kopien der Elemente (der Datenpuffer) von A1
. So hat A2
Zeiger auf die gleichen Objekte wie A1
.
Die 'xy' hat den Zeiger in A1
geändert, aber die A2
Kopie nicht geändert.
Die Änderung 'yy' änderte die Liste, auf die A1
zeigt. A2
hat einen Zeiger auf die gleiche Liste, so dass es die Änderung sieht.
Beachten Sie, dass L
, sieht die ursprüngliche verschachtelte Liste die gleiche Änderung:
In [152]: L
Out[152]: [[[['yy', 1], 2, 3]]]
A3 = A[:]
erzeugt eine view
von A1
. A3
hat den gleichen Datenpuffer wie A1
, so sieht es alle Änderungen.
A4 = A
würde auch die gleichen Änderungen sehen, aber A4
ist eine neue Referenz auf A1
, keine Ansicht oder eine Kopie.
Die duplicate answer
, die früher angesprochen wurde, behandelt Referenzen, Kopien und tiefe Kopien von Listen. Das ist hier relevant, weil L
eine Liste ist und A1
ein Objekt-Array ist, das in vielerlei Hinsicht ein Array-Wrapper um eine Liste ist. Aber A1
ist auch Numy Array, die die Unterscheidung zwischen view
und copy
hat.
Dies ist keine gute Verwendung von numpy
Arrays, nicht einmal die Objekt dtype Version. Es ist ein lehrreiches Beispiel, aber zu verwirrend, um praktisch zu sein. Wenn Sie eine deepcopy
für ein Array tun müssen, verwenden Sie wahrscheinlich Arrays falsch.
Da Sie herausgefunden haben, dass nur eine tiefe Kopie dies verhindert, was verwirren Sie? In den anderen Fällen kopieren Sie * Verweise auf dasselbe veränderbare Objekt *. – jonrsharpe
Es ist, weil Sie ein Array mit 'dtype = object' haben ... Grundsätzlich haben Sie ein Array, das einen Verweis auf eine Python-Liste und 2 Python-Ganzzahlen enthält. Wenn Sie das Array kopieren, kopiert es nur die Referenzen. – mgilson
Ich mag das Duplikat nicht. Numpy-Arrays haben spezielle Kopierprobleme. Und 'dtype' Objekt-Arrays komplizieren das Problem weiter. Diese Frage sollte erneut geöffnet werden. – hpaulj