Welche Regeln verwendet Pandas, um eine Ansicht gegenüber einer Kopie zu generieren?

118

Ich bin verwirrt über die Regeln, die Pandas verwendet, wenn er entscheidet, dass eine Auswahl aus einem Datenrahmen eine Kopie des ursprünglichen Datenrahmens oder eine Ansicht des Originals ist.

Wenn ich zum Beispiel habe

df = pd.DataFrame(np.random.randn(8,8), columns=list('ABCDEFGH'), index=range(1,9))

Ich verstehe, dass ein queryeine Kopie zurückgibt, so dass so etwas wie

foo = df.query('2 < index <= 5')
foo.loc[:,'E'] = 40

hat keine Auswirkung auf den ursprünglichen Datenrahmen df. Ich verstehe auch, dass skalare oder benannte Slices eine Ansicht zurückgeben, so dass Zuweisungen zu diesen, wie z

df.iloc[3] = 70

oder

df.ix[1,'B':'E'] = 222

wird sich ändern df. Aber ich bin verloren, wenn es um kompliziertere Fälle geht. Beispielsweise,

df[df.C <= df.B] = 7654321

Änderungen df, aber

df[df.C <= df.B].ix[:,'B':'E']

nicht.

Gibt es eine einfache Regel, die Pandas verwendet und die ich nur vermisse? Was ist in diesen speziellen Fällen los? und insbesondere, wie ändere ich alle Werte (oder eine Teilmenge von Werten) in einem Datenrahmen, die eine bestimmte Abfrage erfüllen (wie ich es im letzten Beispiel oben versuche)?


Hinweis: Dies ist nicht dasselbe wie diese Frage . und ich habe die Dokumentation gelesen , bin aber nicht davon aufgeklärt. Ich habe auch die "verwandten" Fragen zu diesem Thema gelesen, aber mir fehlt immer noch die einfache Regel, die Pandas verwendet, und wie ich sie anwenden würde, um beispielsweise die Werte (oder eine Teilmenge von Werten) zu ändern. in einem Datenrahmen, der eine bestimmte Abfrage erfüllt.

orome
quelle

Antworten:

138

Hier sind die Regeln, nachfolgende Überschreibung:

  • Alle Operationen erzeugen eine Kopie

  • Wenn inplace=Truevorhanden, wird es an Ort und Stelle geändert. Nur einige Operationen unterstützen dies

  • Ein Indexer, der z .loc/.iloc/.iat/.at. B. gesetzt wird , wird an Ort und Stelle gesetzt.

  • Ein Indexer, der auf ein Objekt mit einem d-Typ zugreift, ist fast immer eine Ansicht (je nach Speicherlayout ist dies möglicherweise nicht der Fall, weshalb dies nicht zuverlässig ist). Dies dient hauptsächlich der Effizienz. (Das obige Beispiel ist für .query; dies gibt immer eine Kopie zurück, wie sie von ausgewertet wird. numexpr)

  • Ein Indexer, der auf ein Objekt mit mehreren d-Typen zugreift, ist immer eine Kopie.

Ihr Beispiel von chained indexing

df[df.C <= df.B].loc[:,'B':'E']

Es wird nicht garantiert, dass es funktioniert (und daher sollten Sie dies niemals tun).

Tun Sie stattdessen:

df.loc[df.C <= df.B, 'B':'E']

da dies schneller ist und immer funktionieren wird

Die verkettete Indizierung besteht aus 2 separaten Python-Operationen und kann daher von Pandas nicht zuverlässig abgefangen werden (Sie erhalten häufig eine SettingWithCopyWarning, aber das ist auch nicht zu 100% erkennbar). Die Entwicklerdokumente , auf die Sie hingewiesen haben, bieten eine viel ausführlichere Erklärung.

Jeff
quelle
3
.querywird IMMER eine Kopie zurückgeben, weil sie funktioniert (und keine Ansicht), weil sie von n numexpr ausgewertet wird. Also werde ich das zu den 'Regeln' hinzufügen
Jeff
3
pandas verlässt sich auf numpy, um zu bestimmen, ob eine Ansicht generiert wird. In einem einzelnen d-Typ-Fall (der eine 1-d für eine Serie, eine 2-d für einen Frame usw. sein kann). numpy kann eine Ansicht erzeugen; es hängt davon ab, was Sie schneiden; Manchmal kann man sich ein Bild machen und manchmal nicht. pandas verlässt sich überhaupt nicht auf diese Tatsache, da es nicht immer offensichtlich ist, ob eine Ansicht generiert wird. Dies spielt jedoch keine Rolle, da loc beim Einstellen nicht darauf angewiesen ist. Bei der Kettenindizierung ist dies jedoch sehr wichtig (und daher ist die Kettenindizierung schlecht)
Jeff,
3
Vielen Dank Jeff, Ihre Antwort ist sehr nützlich. Was ist Ihre Quelle / Referenz zu diesem Thema?
Kamixave
4
Dann erstmal vielen Dank für Ihre großartige Arbeit! Und zweitens, wenn Sie genug Zeit haben, wäre es großartig, einen Absatz hinzuzufügen, der Ihrer Hauptantwort im Dokument ähnelt.
Kamixave
2
sicherlich würde man eine Pull-Anfrage nehmen, um die Dokumente hinzuzufügen / zu überarbeiten. Tue es.
Jeff