2014-01-30 4 views
13

Ich habe gelesen link auf "Rückgabe einer Ansicht gegen eine Kopie". Ich verstehe nicht wirklich, wie die verkettete Zuordnung Konzept in Pandas funktioniert und wie die Verwendung von .ix(), .iloc() oder .loc() betrifft es.Pandas: Angekettete Zuweisungen

Ich bekomme die SettingWithCopyWarning Warnungen für die folgenden Zeilen des Codes, wo data ein Panda Datenrahmen und amount ist eine Spalte (Serie) Name in dem Datenrahmen:

data['amount'] = data['amount'].astype(float) 

data["amount"].fillna(data.groupby("num")["amount"].transform("mean"), inplace=True) 

data["amount"].fillna(mean_avg, inplace=True) 

an diesem Code suchen, ist es offensichtlich, dass ich etwas suboptimales mache? Wenn ja, können Sie mir die Ersatzcodezeilen mitteilen?

Ich bin mir bewusst, der unter Warnung und denken, dass die Warnungen in meinem Fall sind Fehlalarme:

Die verkettete Zuweisung Warnungen/Ausnahmen die Benutzer einer möglicherweise ungültigen Zuordnung informieren wollen. Es kann falsche Positive geben; Situationen, in denen eine verkettete Zuweisung versehentlich gemeldet wird.

EDIT: der Code auf der ersten Kopie Warnung Fehler führt.

data['amount'] = data.apply(lambda row: function1(row,date,qty), axis=1) 
data['amount'] = data['amount'].astype(float) 

def function1(row,date,qty): 
    try: 
     if(row['currency'] == 'A'): 
      result = row[qty] 
     else: 
      rate = lookup[lookup['Date']==row[date]][row['currency'] ] 
      result = float(rate) * float(row[qty]) 
     return result 
    except ValueError: # generic exception clause 
     print "The current row causes an exception:" 

Antwort

18

Der Punkt der SettingWithCopy ist, den Benutzer zu warnen, dass Sie können werden, etwas zu tun, das den ursprünglichen Datenrahmen aktualisiert, wie man erwarten könnte.

Hier ist data ein Datenrahmen, möglicherweise von einem einzigen Dtyp (oder nicht). Sie nehmen dann einen Verweis auf diese data['amount'], die eine Serie ist, und aktualisieren sie. Dies funktioniert wahrscheinlich in Ihrem Fall, weil Sie den gleichen Dateityp wie vorhanden zurückgeben.

Aber es könnte eine Kopie erstellen, die eine Kopie von data['amount'] aktualisiert, die Sie nicht sehen würden; Dann würden Sie sich wundern, warum es nicht aktualisiert wird.

Pandas gibt in fast allen Methodenaufrufen eine Kopie eines Objekts zurück. Die inplace-Operationen sind eine Convience-Operation, die funktioniert, aber im Allgemeinen ist nicht klar, dass Daten geändert werden und möglicherweise an Kopien arbeiten können.

Viel mehr klar, dies zu tun:

data['amount'] = data["amount"].fillna(data.groupby("num")["amount"].transform("mean")) 

data["amount"] = data['amount'].fillna(mean_avg) 

Ein weiteres Plus für die Kopien arbeiten. Sie können Operationen verketten, dies ist nicht möglich mit inplace Einsen.

z.B.

data['amount'] = data['amount'].fillna(mean_avg)*2 

Und nur ein FYI. inplace Operationen sind weder schneller noch speichereffizienter. my2c sie sollten verboten werden. Aber zu spät für diese API.

Sie können dies natürlich auch deaktivieren:

pd.set_option('chained_assignment',None) 

Pandas läuft mit der gesamten Testsuite mit diesem Satz zu raise (so wissen wir, ob Verkettungs geschieht) auf, FYI.

+0

Danke Jeff, also sollte ich idealerweise die 'inplace' Parameter für die 2. und 3. Warnung entfernen. In Bezug auf die erste, d.h. "data ['amount'] = data ['amount']. Astype (float)", was wäre ein Ersatz, der die Kopierwarnung nicht erzeugt? – Rhubarb

+0

Sie müssen etwas * vor * der Astype-Zuweisung tun. Kannst du mehr Code zeigen? – Jeff

+0

sicher, ich habe den Code zu meiner Frage hinzugefügt. – Rhubarb