Super einfache Spaltenzuordnung
Ein Pandas-Datenrahmen wird als geordnetes Diktat von Spalten implementiert.
Dies bedeutet, dass mit dem __getitem__
[]
nicht nur eine bestimmte Spalte abgerufen werden __setitem__
[] =
kann , sondern auch eine neue Spalte zugewiesen werden kann.
Beispielsweise kann diesem Datenrahmen eine Spalte hinzugefügt werden, indem einfach 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 dann funktioniert, wenn der Index des Datenrahmens deaktiviert ist.
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 richtige Weg, aber aufgepasst!
Wenn Sie jedoch einen haben pd.Series
und versuchen, ihn einem Datenrahmen zuzuweisen, in dem die Indizes deaktiviert sind, treten Probleme auf. Siehe 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 a pd.Series
standardmäßig einen Index von 0 bis n hat. Und die Pandas- [] =
Methode versucht , "klug" zu sein.
Was ist eigentlich los?
Wenn Sie die [] =
Methode verwenden, führt pandas stillschweigend eine äußere Verknüpfung oder eine äußere Zusammenführung unter Verwendung des Index des linken Datenrahmens und des Index der rechten Reihe durch.df['column'] = series
Randnotiz
Dies führt schnell zu kognitiven Dissonanzen, da die []=
Methode versucht, abhängig von der Eingabe viele verschiedene Dinge zu tun, und das Ergebnis nur vorhergesagt werden kann, wenn Sie nur wissen, wie Pandas funktionieren. Ich würde daher von den []=
In-Code-Basen abraten, aber wenn Sie Daten in einem Notizbuch untersuchen, ist dies in Ordnung.
Das Problem umgehen
Wenn Sie eine haben pd.Series
und möchten, dass sie von oben nach unten zugewiesen wird, oder wenn Sie produktiven Code codieren und sich der Indexreihenfolge nicht sicher sind, lohnt es sich, diese Art von Problem zu schützen.
Sie könnten das pd.Series
auf a np.ndarray
oder a herabstürzen list
, dies wird den Trick tun.
df['protected'] = pd.Series(['no', 'no', 'no', 'yes']).values
oder
df['protected'] = list(pd.Series(['no', 'no', 'no', 'yes']))
Dies ist jedoch nicht sehr explizit.
Ein Programmierer könnte mitkommen und sagen: "Hey, das sieht überflüssig aus, ich optimiere das einfach weg."
Expliziter Weg
Das Festlegen des Index von pd.Series
als Index von df
ist explizit.
df['protected'] = pd.Series(['no', 'no', 'no', 'yes'], index=df.index)
Oder realistischer, Sie haben wahrscheinlich bereits eine pd.Series
.
protected_series = pd.Series(['no', 'no', 'no', 'yes'])
protected_series.index = df.index
3 no
2 no
1 no
0 yes
Kann jetzt 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
Alternativer Weg mit df.reset_index()
Da die Indexdissonanz das Problem ist, können Sie den Index einfach löschen, wenn Sie der Meinung sind, dass der Index des Datenrahmens keine Vorgaben machen sollte. Dies sollte schneller sein, ist aber nicht sehr sauber, da Ihre Funktion jetzt wahrscheinlich 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
Während df.assign
machen es noch deutlicher , was Sie tun, es hat eigentlich alle dieselben Probleme wie die oben[]=
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
Pass nur auf, df.assign
dass deine Kolumne nicht aufgerufen wird self
. Es wird Fehler verursachen. Dies macht df.assign
stinkend , 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önnen sagen: "Nun, ich werde dann einfach nicht verwenden self
". Aber wer weiß, wie sich diese Funktion in Zukunft ändert, um neue Argumente zu unterstützen. Möglicherweise ist Ihr Spaltenname ein Argument in einem neuen Update von Pandas, das Probleme beim Upgrade verursacht.