2016-06-28 13 views
2

ich mit einem Datenrahmen ‚Kopie‘ erstellt von gerade arbeite Unter Einstellung eines vorherigen - siehe unten:Python Pandas SettingWithCopyWarning Kopien vs neue Objekte

import random 
import pandas as pd 
df = pd.DataFrame({'data':list(random.sample(range(10,100),25))}) 
df_filtered = df.query('data > 20 and data < 80') 
df_filtered.rename(columns={'data':'observations'},inplace=True) 

Das Problem ist, wenn die Umbenennungs Methode, die ich genannt wird empfange eine Warnung von SettingWithCopy, die, so wie ich es verstehe, bedeutet, dass ich an einer Kopie des ursprünglichen (df in diesem Fall) Objekts arbeite. Der Warnungstext lautet: "Ein Wert versucht, auf eine Kopie eines Segments aus einem DataFrame festgelegt zu werden"

Ich fand this question, die mit einem anderen Ansatz zur Untergruppe beantwortet wurde. Ich bevorzuge die Dataframe.query() -Methode selbst (Syntax-weise). Gibt es eine Möglichkeit, ein neues Dataframe-Objekt mit der Methode .query() anstelle der vorgeschlagenen Methode in der Frage, die ich verknüpft habe, zu erstellen? Ich habe ein paar Optionen mit Iloc ausprobiert, bin aber bisher noch nicht erfolgreich gewesen.

+0

mit inplace=True und verwenden df = df.function(...) Technik zu vermeiden Was ist Ihr Ziel ? Möchten Sie einen DF mit unabhängigen Werten (eine Kopie) haben? Hinweis: es kostet zusätzlichen Speicher. – MaxU

+0

In diesem Beispiel war meine Absicht für df_filtered, ein anderes und unabhängiges Objekt als df zu sein. Ich weiß, dass beide Objekte im Speicher sind, aber das ist in Ordnung für dieses Beispiel. – Sevyns

Antwort

1

versuchen, diese stattdessen inplace=True verwenden:

In [12]: df_filtered = df.query('data > 20 and data < 80') 

In [13]: df_filtered = df_filtered.rename(columns={'data':'observations'}) 

.rename() Funktion gibt ein neues Objekt, so dass Sie einfach Ihre DF mit dem zurückgegebenen neuen DF

wenn Sie inplace verwenden überschreiben kann das folgende geschieht

von docs:

Inplace: Boolean, Standard Falsch

Gibt an, ob ein neuer DataFrame zurückgegeben werden soll. Wenn True, wird der Wert der Kopie ignoriert.

Returns:

umbenannt: Datenrahmen (neues Objekt)

PS versuchen Sie sollten grundsätzlich statt

+0

Danke Max - die Warnung ging weg, aber warum sollte eine erzwingende Zuweisung funktionieren, wenn der Inplace-Parameter nicht funktioniert? Ich nehme an, ich könnte mich daran gewöhnen, aber ich würde gerne verstehen, warum das über das hinausgeht, was ich versucht habe ... irgendwelche Gedanken? – Sevyns

+2

Warum sollten Sie "vermeiden inplace = True verwenden und df = df.function (...)" verwenden – Merlin

4

Sie können eine Kopie immer explizit erstellen, indem Sie .copy() auf Ihrem gefilterten Datenframe aufrufen. Konkret ersetzen

mit

df_filtered = df.query('data > 20 and data < 80').copy() 

Heißt das loszuwerden, die Warnung erhalten?

+0

Das hat auch dafür gesorgt. Wenn ich also die Kopierfunktion nicht anrufe, erzeugt Pandas einen anderen Objekttyp, wenn Sie einen Dataframe (und nicht ein neues Objekt) unterteilen? Ich habe versucht, die Dokumentation zu lesen, aber ich verstehe nicht, was gerade passiert ... meine größte Sorge ist, dass ich sicherstellen will, dass es tut, was ich will. – Sevyns

+1

Ohne Aufruf von '.copy()', 'df_filtered' kann eine Ansicht des ursprünglichen' df' sein. Es gibt keine Möglichkeit, dies bis zur Laufzeit zu wissen. Deshalb bekommst du die Warnung.Es gibt viele defensive Kopien im Pandas-Code, aber es ist nicht universell - oft möchten Sie eine Ansicht statt einer Kopie. –

+0

Danke für die Info Alberto! Weißt du, ob die von Max vorgeschlagene Methode (wo die Zuweisung direkt mit einem Gleichheitsoperator statt mit dem Parameter inplace erfolgt) sich genauso verhält wie das explizite Aufrufen von copy() fn? Ich versuche nur zu verstehen, ob es mehr Nuance-Verhalten gibt, auf das ich achten sollte :) – Sevyns