Einfache Spaltenzuweisung
Ein Pandas-DataFrame ist als geordnetes Wörterbuch von Spalten implementiert.
Dies bedeutet, dass das __getitem__
[]
nicht nur verwendet werden kann, um eine bestimmte Spalte abzurufen, sondern auch __setitem__
[] =
verwendet werden kann, um eine neue Spalte zuzuweisen.
Zum Beispiel kann dieser DataFrame einfach eine Spalte hinzugefügt werden, indem der []
Accessor verwendet wird
size name color
0 big rose red
1 small violet blue
2 small tulip red
3 small harebell blue
df['protected'] = ['no', 'no', 'no', 'yes']
size name color protected
0 big rose red no
1 small violet blue no
2 small tulip red no
3 small harebell blue yes
Beachten Sie, dass dies auch funktioniert, wenn der Index des DataFrames nicht übereinstimmt.
df.index = [3,2,1,0]
df['protected'] = ['no', 'no', 'no', 'yes']
size name color protected
3 big rose red no
2 small violet blue no
1 small tulip red no
0 small harebell blue yes
[] = ist der Weg, aber Vorsicht!
Wenn Sie jedoch eine pd.Series
haben und versuchen, sie einem DataFrame zuzuweisen, bei dem die Indizes nicht übereinstimmen, werden Sie auf Probleme stoßen. Sehen Sie das Beispiel:
df['protected'] = pd.Series(['no', 'no', 'no', 'yes'])
size name color protected
3 big rose red yes
2 small violet blue no
1 small tulip red no
0 small harebell blue no
Dies liegt daran, dass eine pd.Series
standardmäßig einen Index hat, der von 0 bis n aufgezählt wird. Und die pandas [] =
Methode versucht “intelligent” zu sein
Was tatsächlich passiert.
Wenn Sie die [] =
Methode verwenden, führt Pandas stillschweigend ein Outer Join oder Outer Merge unter Verwendung des Index des linken DataFrames und des Index der rechten Serie durch. df['Spalte'] = Serie
Nebenbei bemerkt
Dies führt schnell zu kognitiver Dissonanz, da die [] =
Methode je nach Eingabe viele verschiedene Dinge zu tun versucht und das Ergebnis nicht vorhergesagt werden kann, es sei denn, Sie wissen einfach, wie Pandas funktioniert. Ich würde daher von der Verwendung von [] =
in Codebasen abraten, aber wenn Sie Daten in einem Notebook erkunden, ist es in Ordnung.
Umgehung des Problems
Wenn Sie eine pd.Series
haben und sie von oben nach unten zuweisen möchten, oder wenn Sie produktiven Code schreiben und sich nicht sicher sind, in welcher Reihenfolge die Indizes stehen, lohnt es sich, sich gegen diese Art von Problem abzusichern.
Sie könnten die pd.Series
in ein np.ndarray
oder eine list
umwandeln, das wird das Problem lösen.
df['protected'] = pd.Series(['no', 'no', 'no', 'yes']).values
oder
df['protected'] = list(pd.Series(['no', 'no', 'no', 'yes']))
Aber das ist nicht sehr explizit.
Einige Programmierer könnten kommen und sagen "Hey, das sieht redundant aus, ich werde das einfach optimieren".
Explizite Methode
Das Einstellen des Index der pd.Series
auf den Index des df
ist explizit.
df['protected'] = pd.Series(['no', 'no', 'no', 'yes'], index=df.index)
Oder realistischerweise haben Sie wahrscheinlich bereits eine pd.Series
verfügbar.
protected_series = pd.Series(['no', 'no', 'no', 'yes'])
protected_series.index = df.index
3 no
2 no
1 no
0 yes
Kann nun zugewiesen werden
df['protected'] = protected_series
size name color protected
3 big rose red no
2 small violet blue no
1 small tulip red no
0 small harebell blue yes
Alternative Methode mit df.reset_index()
Da die Indexdifferenz das Problem ist, wenn Sie der Meinung sind, dass der Index des DataFrames nicht die Dinge diktiert, können Sie einfach den Index löschen, das sollte schneller sein, aber es ist nicht sehr sauber, da Ihre Funktion jetzt vermutlich zwei Dinge tut.
df.reset_index(drop=True)
protected_series.reset_index(drop=True)
df['protected'] = protected_series
size name color protected
0 big rose red no
1 small violet blue no
2 small tulip red no
3 small harebell blue yes
Hinweis zu df.assign
Obwohl df.assign
deutlicher macht, was Sie tun, hat es tatsächlich alle Probleme wie das oben genannte [] =
df.assign(protected=pd.Series(['no', 'no', 'no', 'yes']))
size name color protected
3 big rose red yes
2 small violet blue no
1 small tulip red no
0 small harebell blue no
Achten Sie nur bei df.assign
darauf, dass Ihre Spalte nicht self
genannt wird. Es wird Fehler verursachen. Das macht df.assign
schwierig, da es diese Art von Artefakten in der Funktion gibt.
df.assign(self=pd.Series(['no', 'no', 'no', 'yes'])
TypeError: assign() got multiple values for keyword argument 'self'
Sie könnten sagen: "Nun, ich werde einfach kein self
verwenden". Aber wer weiß, wie sich diese Funktion in der Zukunft ändert, um neue Argumente zu unterstützen. Vielleicht wird Ihr Spaltenname in einem neuen Update von Pandas ein Argument sein, das beim Upgrade Probleme verursacht.