Inplace verstehen = True

103

In der pandasBibliothek gibt es häufig die Möglichkeit, das Objekt an Ort und Stelle zu ändern, z. B. mit der folgenden Anweisung ...

df.dropna(axis='index', how='all', inplace=True)

Ich bin gespannt, was zurückgegeben wird und wie das Objekt behandelt wird, wenn inplace=Truees übergeben wird und wann inplace=False.

Ändern sich alle Vorgänge selfwann inplace=True? Und wann inplace=Falsewird sofort ein neues Objekt erstellt new_df = selfund dann new_dfzurückgegeben?

Aran Freel
quelle
13
Ja, inplace=Truereturn None inplace=Falsegibt eine Kopie des Objekts mit der ausgeführten Operation zurück. Die Dokumente sind diesbezüglich ziemlich klar. Gibt es etwas, das mit einem bestimmten Teil verwirrt? SpeficallyIf True, do operation inplace and return None.
EdChum
Ich unterteile das DataFrame-Objekt und mit einer Operation wie Merge scheint es nicht möglich zu sein, es an Ort und Stelle auszuführen ... self = self.merge(new_df, how='left', on='column2' Ich bin nicht sicher, ob es möglich ist, sich selbst neu zuzuweisen
Aran Freel
1
Sie haben Recht, dass DataFrame.merge kein inplaceArgument hat. Es wird ein DataFrame zurückgegeben, sodass kein Problem bei der Neuzuweisung auftritt.
JAV
Kann jemand auch die Vorteile der Verwendung im Hinblick auf den Ressourcenverbrauch hervorheben?
Markroxor
2
@markroxor Es gibt wirklich nicht viele. In einigen Fällen kann die inplaceAktion etwas schneller sein, da Sie keine Kopie des Ergebnisses zurückgeben müssen. Aber das war es schon. Es gibt viel mehr Gründe, es nicht zu benutzen.
CS95

Antworten:

95

Wenn inplace=Truedie Daten übergeben werden, werden sie an Ort und Stelle umbenannt (es wird nichts zurückgegeben). Sie würden also Folgendes verwenden:

df.an_operation(inplace=True)

Wenn übergeben inplace=Falsewird (dies ist der Standardwert, daher nicht erforderlich), führt der Vorgang aus und gibt eine Kopie des Objekts zurück, sodass Sie Folgendes verwenden würden:

df = df.an_operation(inplace=False) 
ECH
quelle
Wäre es richtig zu denken, dass dies inplacenur eine Option für Methoden ist, die vorhandene Daten ändern, aber nicht für Methoden, die die Daten "umformen". Zum Beispiel kann ich .set_index (inplace = True) verwenden, da dies Werte auf den vorhandenen Index anwendet, aber nicht .reindex (inplace = True), da dadurch zusätzliche Zeilen im DataFrame erstellt werden können, die im vorherigen Array nicht vorhanden waren ?
AC24
4
Die Methode .dropna()akzeptiert inplace=Trueden Datenrahmen und kann ihn definitiv umformen, also nein.
Jorijnsmit
3
Hier muss man vorsichtig sein. @ ac24 ist eigentlich mehr oder weniger richtig. Während dropnaein Datenrahmen mit einer anderen Form zurückgegeben wird, werden die zugrunde liegenden Daten nicht tatsächlich umgeformt - es wird lediglich eine Maske darüber zurückgegeben (wann inplace=False), was zu den gefürchteten Daten führen kann SettingWithCopyWarning. Nur wenn keine Verweise mehr auf das alte Wertearray vorhanden sind, werden Pandas entsprechend der Maske neu geformt. Eine bessere Faustregel lautet: inplaceIst verfügbar, wenn für die Operation kein neues Hintergrund-Narrar von Werten zugewiesen werden muss.
BallpointBen
46

Ich benutze es so

# Have to assign back to dataframe (because it is a new copy)
df = df.some_operation(inplace=False) 

Oder

# No need to assign back to dataframe (because it is on the same copy)
df.some_operation(inplace=True)

FAZIT:

 if inplace is False
      Assign to a new variable;
 else
      No need to assign
Nabin
quelle
5
Hallo @Nabin, das ist viel zu klar für jeden, der an Pandas und Numpy arbeitet :-)
Vetrivel PS
44

Wird bei Pandas inplace = True als schädlich angesehen oder nicht?

TLDR; Ja Ja es ist.

  • inplaceIm Gegensatz zu dem, was der Name andeutet, verhindert dies häufig nicht die Erstellung von Kopien und bietet (fast) nie Leistungsvorteile
  • inplace funktioniert nicht mit Methodenverkettung
  • inplace ist eine häufige Gefahr für Anfänger. Wenn Sie diese Option entfernen, wird die API vereinfacht

Ich rate nicht, diesen Parameter einzustellen, da er wenig Sinn hat . Siehe dieses GitHub-Problem, in dem vorgeschlagen wird, das inplaceArgument api-weit zu verwerfen.

Es ist ein weit verbreitetes Missverständnis, dass die Verwendung inplace=Truezu effizienterem oder optimiertem Code führt. In Wirklichkeit gibt es absolut keine Leistungsvorteile zu verwenden inplace=True. Sowohl die In-Place- als auch die Out-of-Place-Version erstellen ohnehin eine Kopie der Daten , wobei die In-Place-Version die Kopie automatisch zurückweist.

inplace=Trueist eine häufige Gefahr für Anfänger. Zum Beispiel kann es Folgendes auslösenSettingWithCopyWarning :

df = pd.DataFrame({'a': [3, 2, 1], 'b': ['x', 'y', 'z']})

df2 = df[df['a'] > 1]
df2['b'].replace({'x': 'abc'}, inplace=True)
# SettingWithCopyWarning: 
# A value is trying to be set on a copy of a slice from a DataFrame

Das Aufrufen einer Funktion in einer DataFrame-Spalte mit inplace=True kann funktionieren oder nicht . Dies gilt insbesondere dann, wenn es sich um eine verkettete Indizierung handelt.

Als ob die oben beschriebenen Probleme nicht ausreichen, behindert diesinplace=True auch die Verkettung von Methoden . Vergleichen Sie die Arbeitsweise von

result = df.some_function1().reset_index().some_function2()

Im Gegensatz zu

temp = df.some_function1()
temp.reset_index(inplace=True)
result = temp.some_function2()

Ersteres eignet sich für eine bessere Codeorganisation und Lesbarkeit.


Eine weitere unterstützende Behauptung ist, dass die API für set_axiskürzlich so geändert wurde, dass der inplaceStandardwert von True auf False geändert wurde. Siehe GH27600 . Großartige Jobentwickler!

cs95
quelle
Sicher inplace=Truefunktioniert das nicht mit Verkettung usw., aber das ist offensichtlich, wenn Sie verstehen, was es konzeptionell tut. Persönlich finde ich es etwas sauberer, Zuweisungen zu vermeiden. Würden Sie auch dafür sein, list.sortusw. aus der Standardbibliothek zu entfernen ?
Chris_Rands
4
Ich denke nicht, dass das ein fairer Vergleich ist. Es gibt einige offensichtliche Vorteile der Verwendung von list.sort gegenüber sortiert. Gleiches gilt für die anderen vorhandenen Funktionen. Hier gibt es keinen wirklichen Vorteil, Methodenverkettungen sind bei Pandas weitaus häufiger und es gibt ohnehin Pläne für die Ablehnung dieses Arguments.
CS95
Ich finde es auch ein wenig sauberer, eine Zuordnung zu vermeiden: Zum Beispiel list.append()ist auch Python vorhanden , während Pandas df.append nicht vorhanden ist (und nicht einmal Inplace unterstützt), was mich bis zum Äußersten irritiert. Aus diesem Grund möchte ich wissen, nur um zu verstehen, was echte Vorteile sind - was sind die offensichtlichen Vorteile der Verwendung von list.sort gegenüber sortiert, abgesehen von der Vermeidung von Zuweisungen? Ansonsten denke ich, dass es hier einen echten Vorteil gibt - ich kann eine Zuordnung vermeiden, wo ich sie persönlich besser lesbar finde.
SDBBS
1
@sdbbs list.append()wird an eine vorhandene Liste angehängt. df.appendErstellt eine Kopie Ihrer Daten (unabhängig davon, ob Sie 5 oder 5 Millionen Zeilen haben), fügt Ihrer Kopie eine neue Zeile hinzu und gibt sie dann zurück. Was macht Ihrer Meinung nach mehr Sinn? Was df.append betrifft, vermeiden Sie so viel wie möglich . Ich denke nicht, dass es ein gutes Beispiel ist, für inplace = True zu argumentieren. Ich denke nicht einmal, dass diese Funktion einen Platz in der API hat.
cs95
6

Der inplaceParameter:

df.dropna(axis='index', how='all', inplace=True)

in Pandasund allgemein bedeutet:

1. Pandas erstellt eine Kopie der Originaldaten

2. ... berechnet es

3. ... ordnet die Ergebnisse den Originaldaten zu.

4. ... löscht die Kopie.

Wie Sie in den Rest meiner Antwort ist weiter unten lesen können, noch wir können guten Grund haben , diesen Parameter , dh die zu verwenden inplace operations, aber wir sollten es vermeiden , wenn wir können, da es mehr Probleme erzeugen, wie:

1. Ihr Code ist schwerer zu debuggen (Tatsächlich bedeutet SettingwithCopyWarning, Sie vor diesem möglichen Problem zu warnen).

2. Konflikt mit der Methodenverkettung


Es gibt also sogar einen Fall, in dem wir es noch verwenden sollten?

Definitiv Ja. Wenn wir Pandas oder ein anderes Tool zum Behandeln großer Datenmengen verwenden, können wir uns leicht der Situation stellen, in der einige große Datenmengen unseren gesamten Speicher belegen können. Um diesen unerwünschten Effekt zu vermeiden, können wir einige Techniken wie die Verkettung von Methoden verwenden :

(
    wine.rename(columns={"color_intensity": "ci"})
    .assign(color_filter=lambda x: np.where((x.hue > 1) & (x.ci > 7), 1, 0))
    .query("alcohol > 14 and color_filter == 1")
    .sort_values("alcohol", ascending=False)
    .reset_index(drop=True)
    .loc[:, ["alcohol", "ci", "hue"]]
)

Dies macht unseren Code kompakter (obwohl auch schwieriger zu interpretieren und zu debuggen) und verbraucht weniger Speicher, da die verketteten Methoden mit den zurückgegebenen Werten der anderen Methode arbeiten und somit nur eine Kopie der Eingabedaten erhalten. Wir können deutlich sehen, dass wir nach diesen Vorgängen 2 x ursprünglichen Datenspeicherverbrauch haben werden.

Oder wir können inplaceParameter verwenden (obwohl dies auch schwieriger zu interpretieren und zu debuggen ist). Unser Speicherverbrauch beträgt 2 x Originaldaten , aber unser Speicherverbrauch nach diesem Vorgang bleibt 1 x Originaldaten. Wenn jemand mit riesigen Datenmengen genau arbeitet, kann dies ein sein großer Vorteil.


Schlußfolgerung:

Vermeiden Sie die Verwendung von inplaceParametern, es sei denn, Sie arbeiten nicht mit großen Datenmengen und sind sich der möglichen Probleme bewusst, falls diese weiterhin verwendet werden.

Geeocode
quelle
2

Speichern Sie es in derselben Variablen

data["column01"].where(data["column01"]< 5, inplace=True)

Speichern Sie es in einer separaten Variablen

data["column02"] = data["column01"].where(data["column1"]< 5)

Sie können die Variable jedoch jederzeit überschreiben

data["column01"] = data["column01"].where(data["column1"]< 5)

Zu Ihrer Information: In der Standardeinstellung inplace = False

Hyukkyulee
quelle
1

Wenn Sie versuchen, mithilfe einer Funktion Änderungen an einem Pandas-Datenrahmen vorzunehmen, verwenden wir 'inplace = True', wenn wir die Änderungen am Datenrahmen festschreiben möchten. Daher ändert die erste Zeile im folgenden Code den Namen der ersten Spalte in 'df' in 'Noten'. Wir müssen die Datenbank aufrufen, wenn wir die resultierende Datenbank sehen wollen.

df.rename(columns={0: 'Grades'}, inplace=True)
df

Wir verwenden 'inplace = False' (dies ist auch der Standardwert), wenn wir die Änderungen nicht festschreiben möchten, sondern nur die resultierende Datenbank drucken möchten. Tatsächlich wird also eine Kopie der Originaldatenbank mit den festgeschriebenen Änderungen gedruckt, ohne die Originaldatenbank zu ändern.

Um es klarer zu machen, machen die folgenden Codes dasselbe:

#Code 1
df.rename(columns={0: 'Grades'}, inplace=True)
#Code 2
df=df.rename(columns={0: 'Grades'}, inplace=False}
Harsha
quelle
0

inplace=True wird verwendet, je nachdem, ob Sie Änderungen am ursprünglichen df vornehmen möchten oder nicht.

df.drop_duplicates()

zeigt nur abgelegte Werte an, nimmt jedoch keine Änderungen an df vor

df.drop_duplicates(inplace  = True)

löscht Werte und nimmt Änderungen an df vor.

Hoffe das hilft.:)

Shahir Ansari
quelle
0

inplace=Truemacht die Funktion unrein. Es ändert den ursprünglichen Datenrahmen und gibt None zurück. In diesem Fall unterbrechen Sie die DSL-Kette. Da die meisten Datenrahmenfunktionen einen neuen Datenrahmen zurückgeben, können Sie DSL bequem verwenden. Mögen

df.sort_values().rename().to_csv()

Funktionsaufruf mit inplace=TrueRückgabe Keine und DSL-Kette ist unterbrochen. Zum Beispiel

df.sort_values(inplace=True).rename().to_csv()

wird werfen NoneType object has no attribute 'rename'

Ähnliches gilt für Pythons integrierte Sortierung und Sortierung. lst.sort()gibt zurück Noneund sorted(lst)gibt eine neue Liste zurück.

Im Allgemeinen nicht verwenden, es inplace=Truesei denn, Sie haben einen bestimmten Grund dafür. Wenn Sie einen Neuzuweisungscode wie schreiben müssen df = df.sort_values(), versuchen Sie, den Funktionsaufruf in der DSL-Kette anzuhängen, z

df = pd.read_csv().sort_values()...
Louis
quelle
Wenn Sie exakten Arbeitscode mit der richtigen Formatierung bereitstellen, können Benutzer Ihre Antwort schneller verstehen. Ich fordere Sie auf, dasselbe zu tun. Ich bin kein Panda-Experte, kann also Ihre Antwort nicht neu formatieren, aber es wird dringend empfohlen
Anand Vaidya
0

Soweit meine Erfahrung mit Pandas möchte ich antworten.

Das Argument 'inplace = True' steht für den Datenrahmen, der Änderungen dauerhaft machen muss, z.

    df.dropna(axis='index', how='all', inplace=True)

ändert den gleichen Datenrahmen (da diese Pandas NaN-Einträge im Index finden und löschen). Wenn wir es versuchen

    df.dropna(axis='index', how='all')

pandas zeigt den Datenrahmen mit den von uns vorgenommenen Änderungen an, ändert jedoch nicht den ursprünglichen Datenrahmen 'df'.

Chetan
quelle
0

Wenn Sie nicht inplace = True oder inplace = False verwenden, erhalten Sie im Grunde eine Kopie zurück.

Also zum Beispiel:

testdf.sort_values(inplace=True, by='volume', ascending=False)

ändert die Struktur mit den Daten in absteigender Reihenfolge.

dann:

testdf2 = testdf.sort_values( by='volume', ascending=True)

macht testdf2 zu einer Kopie. Die Werte sind alle gleich, aber die Sortierung wird umgekehrt und Sie haben ein unabhängiges Objekt.

Dann geben Sie eine weitere Spalte, sagen Sie LongMA und Sie tun:

testdf2.LongMA = testdf2.LongMA -1

Die LongMA-Spalte in testdf enthält die ursprünglichen Werte und testdf2 die dekrementierten Werte.

Es ist wichtig, den Unterschied im Auge zu behalten, wenn die Berechnungskette wächst und die Kopien von Datenrahmen ihren eigenen Lebenszyklus haben.

Ryan Hunt
quelle
0

Ja, in Pandas haben wir viele Funktionen, die den Parameter haben, inplaceaber standardmäßig zugewiesen sind False.

Wenn Sie also der df.dropna(axis='index', how='all', inplace=False)Meinung sind, dass Sie das Original nicht ändern möchten DataFrame, wird stattdessen eine neue Kopie mit den erforderlichen Änderungen für Sie erstellt .

Aber wenn Sie den inplaceParameter auf ändernTrue

Dann ist es gleichbedeutend damit, explizit zu sagen, dass ich keine neue Kopie der möchte, DataFramesondern die Änderungen an der angegebenen vornehmenDataFrame

Dies zwingt den Python-Interpreter, keine neuen zu erstellenDataFrame

Sie können die Verwendung des inplaceParameters jedoch auch vermeiden, indem Sie das Ergebnis dem ursprünglichen DataFrame neu zuweisen

df = df.dropna(axis='index', how='all')


quelle