Verwenden Sie die ursprünglichen df1-Indizes, um die Serie zu erstellen:
df1['e'] = pd.Series(np.random.randn(sLength), index=df1.index)
Edit 2015
Einige berichteten, dass sie das SettingWithCopyWarning
mit diesem Code bekommen haben.
Der Code läuft jedoch immer noch perfekt mit der aktuellen Pandas-Version 0.16.1.
>>> sLength = len(df1['a'])
>>> df1
a b c d
6 -0.269221 -0.026476 0.997517 1.294385
8 0.917438 0.847941 0.034235 -0.448948
>>> df1['e'] = pd.Series(np.random.randn(sLength), index=df1.index)
>>> df1
a b c d e
6 -0.269221 -0.026476 0.997517 1.294385 1.757167
8 0.917438 0.847941 0.034235 -0.448948 2.228131
>>> p.version.short_version
'0.16.1'
Die SettingWithCopyWarning
Ziele einer möglicherweise ungültigen Zuordnung auf einer Kopie des Datenrahmen zu informieren. Es heißt nicht unbedingt, dass Sie es falsch gemacht haben (es kann falsch positive Ergebnisse auslösen), aber ab 0.13.0 werden Sie darüber informiert, dass es für denselben Zweck geeignetere Methoden gibt. Wenn Sie dann die Warnung erhalten, befolgen Sie einfach die Anweisungen : Verwenden Sie stattdessen .loc [row_index, col_indexer] = value
>>> df1.loc[:,'f'] = pd.Series(np.random.randn(sLength), index=df1.index)
>>> df1
a b c d e f
6 -0.269221 -0.026476 0.997517 1.294385 1.757167 -0.050927
8 0.917438 0.847941 0.034235 -0.448948 2.228131 0.006109
>>>
Tatsächlich ist dies derzeit die effizientere Methode, wie in Pandas-Dokumenten beschrieben
2017 bearbeiten
Wie in den Kommentaren und von @Alexander angegeben, könnte die derzeit beste Methode zum Hinzufügen der Werte einer Serie als neue Spalte eines DataFrame Folgendes verwenden assign
:
df1 = df1.assign(e=pd.Series(np.random.randn(sLength)).values)
SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_index,col_indexer] = value instead
kwargs
Wörterbuch wie folgt entpacken :df1 = df1.assign(**{'e': p.Series(np.random.randn(sLength)).values})
Dies ist die einfache Möglichkeit, eine neue Spalte hinzuzufügen:
df['e'] = e
quelle
e
(Series(np.random.randn(sLength))
) eine indizierte Serie 0-n generiert. Wenn Sie dies df1 zuweisen, erhalten Sie einige NaN-Zellen.my_dataframe = pd.DataFrame(columns=('foo', 'bar'))
. Zurücksetzen Ihrer BearbeitungIch gehe davon aus, dass die Indexwerte in
e
denen in übereinstimmendf1
.Der einfachste Weg, eine neue Spalte mit dem Namen zu initiieren
e
und ihr die Werte aus Ihrer Serie zuzuweisene
:zuweisen (Pandas 0.16.0+)
Ab Pandas 0.16.0 können Sie auch verwenden
assign
, um einem DataFrame neue Spalten zuzuweisen und ein neues Objekt (eine Kopie) mit allen ursprünglichen Spalten zusätzlich zu den neuen zurückzugeben.Gemäß diesem Beispiel (das auch den Quellcode der
assign
Funktion enthält) können Sie auch mehr als eine Spalte einschließen:Im Zusammenhang mit Ihrem Beispiel:
Die Beschreibung dieser neuen Funktion bei ihrer Einführung finden Sie hier .
quelle
df['e'] = e.values
) keine Kopie des Datenrahmens erstellt, während die zweite Option (usingdf.assign
) dies tut? In Fällen, in denen viele neue Spalten nacheinander hinzugefügt werden und große Datenrahmen vorhanden sind, würde ich eine viel bessere Leistung der ersten Methode erwarten.assign
besteht darin, dass Sie Ihre Vorgänge miteinander verketten.df.assign(**df.mean().add_prefix('mean_'))
df_new = pd.concat([df1, df2], axis=1)
, wobei Sie diesignore_index=False
standardmäßig beachten .Es scheint, dass in neueren Pandas-Versionen df.assign verwendet werden muss :
df1 = df1.assign(e=np.random.randn(sLength))
Es produziert nicht
SettingWithCopyWarning
.quelle
Dies direkt über NumPy zu tun, ist am effizientesten:
Beachten Sie, dass mein ursprünglicher (sehr alter) Vorschlag lautete
map
(was viel langsamer ist):quelle
.map
um vorhandene Serien anstelle von zu verwendenlambda
? Ich versuchedf1['e'] = df1['a'].map(lambda x: e)
oderdf1['e'] = df1['a'].map(e)
aber es ist nicht was ich brauche. (Ich bin neu in Pyhon und Ihre vorherige Antwort hat mir bereits geholfen)e
als Serie haben, müssen Sie nicht verwendenmap
, verwenden Siedf['e']=e
(@joaquins Antwort).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 wirdBeachten Sie, dass dies auch dann funktioniert, wenn der Index des Datenrahmens deaktiviert ist.
[] = 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: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 anp.ndarray
oder a herabstürzenlist
, dies wird den Trick tun.oder
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 vondf
ist explizit.Oder realistischer, Sie haben wahrscheinlich bereits eine
pd.Series
.Kann jetzt zugewiesen werden
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.
Hinweis zu
df.assign
Während
df.assign
machen es noch deutlicher , was Sie tun, es hat eigentlich alle dieselben Probleme wie die oben[]=
Pass nur auf,
df.assign
dass deine Kolumne nicht aufgerufen wirdself
. Es wird Fehler verursachen. Dies machtdf.assign
stinkend , da es diese Art von Artefakten in der Funktion gibt.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.quelle
[] =
Methode verwenden, führt pandas leise einen äußeren Join oder eine äußere Zusammenführung durch. " Dies ist die wichtigste Information im gesamten Thema. Aber können Sie einen Link zur offiziellen Dokumentation zur Funktionsweise des[]=
Betreibers bereitstellen ?Einfachste Möglichkeiten: -
Auf diese Weise vermeiden Sie die sogenannte verkettete Indizierung, wenn Sie neue Werte in einem Pandas-Objekt festlegen. Klicken Sie hier, um weiterzulesen .
quelle
Wenn Sie die gesamte neue Spalte auf einen anfänglichen Basiswert setzen möchten (z. B.
None
), können Sie dies tun:df1['e'] = None
Dies würde der Zelle tatsächlich den Typ "Objekt" zuweisen. So können Sie später komplexe Datentypen wie Listen in einzelne Zellen einfügen.
quelle
Ich habe das gefürchtet
SettingWithCopyWarning
und es wurde nicht mit der iloc-Syntax behoben. Mein DataFrame wurde von read_sql aus einer ODBC-Quelle erstellt. Mit einem Vorschlag von Lowtech oben hat Folgendes für mich funktioniert:Dies funktionierte gut, um die Spalte am Ende einzufügen. Ich weiß nicht, ob es am effizientesten ist, aber ich mag keine Warnmeldungen. Ich denke, es gibt eine bessere Lösung, aber ich kann sie nicht finden, und ich denke, es hängt von einem Aspekt des Index ab.
Hinweis . Dass dies nur einmal funktioniert und eine Fehlermeldung ausgibt, wenn versucht wird, eine vorhandene Spalte zu überschreiben.
Hinweis Wie oben und ab 0.16.0 ist die Zuweisung die beste Lösung. Siehe Dokumentation http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.assign.html#pandas.DataFrame.assign Funktioniert gut für Datenflusstypen, bei denen Sie Ihre Zwischenwerte nicht überschreiben.
quelle
list_of_e
mit relevanten Daten.df['e'] = list_of_e
quelle
tolist()
Befehl hilfreich sein.Wenn die Spalte, die Sie hinzufügen möchten, eine Serienvariable ist, dann nur:
Dies funktioniert auch dann gut, wenn Sie eine vorhandene Spalte ersetzen. Geben Sie einfach den Namen new_columns_name ein, der der Spalte entspricht, die Sie ersetzen möchten. Die vorhandenen Spaltendaten werden nur mit den neuen Seriendaten überschrieben.
quelle
Wenn der Datenrahmen und das Serienobjekt denselben Index haben ,
pandas.concat
funktioniert dies auch hier:Falls sie nicht den gleichen Index haben:
quelle
Narrensicher:
Beispiel:
quelle
Lassen Sie mich nur hinzufügen, dass, genau wie bei hum3 ,
.loc
das nicht gelöst wurdeSettingWithCopyWarning
und ich darauf zurückgreifen musstedf.insert()
. In meinem Fall wurde durch "gefälschte" Kettenindizierung ein falsches Positiv generiert.dict['a']['e']
Dabei'e'
handelt es sich um die neue Spalte unddict['a']
einen aus dem Wörterbuch stammenden DataFrame.Beachten Sie auch, dass Sie, wenn Sie wissen, was Sie tun, die Warnung mit
pd.options.mode.chained_assignment = None
einer der anderen hier angegebenen Lösungen ausschalten und dann verwenden können.quelle
Verwenden Sie einfach Dataframe.insert, um eine neue Spalte an einer bestimmten Stelle (0 <= loc <= Anzahl der Spalten) in einen Datenrahmen einzufügen:
Wenn Sie also die Spalte e am Ende eines Datenrahmens mit dem Namen df hinzufügen möchten , können Sie Folgendes verwenden:
Der Wert kann eine Reihe, eine Ganzzahl (in diesem Fall werden alle Zellen mit diesem einen Wert gefüllt) oder eine Array-ähnliche Struktur sein
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.insert.html
quelle
Wenn Sie vor dem Zuweisen einer neuen Spalte Daten indiziert haben, müssen Sie den Index sortieren. Zumindest in meinem Fall musste ich:
quelle
Eine Sache zu beachten ist jedoch, dass, wenn Sie dies tun
Dies wird effektiv ein linker Join im df1.index sein. Wenn Sie also einen äußeren Verknüpfungseffekt erzielen möchten , besteht meine wahrscheinlich unvollständige Lösung darin, einen Datenrahmen mit Indexwerten zu erstellen, die das Universum Ihrer Daten abdecken, und dann den obigen Code zu verwenden. Zum Beispiel,
quelle
Ich suchte nach einer allgemeinen Möglichkeit
numpy.nan
, einem Datenrahmen eine Spalte mit s hinzuzufügen, ohne dumm zu werdenSettingWithCopyWarning
.Aus dem Folgenden:
numpy
Arrays von NaNs inlineIch habe mir das ausgedacht:
quelle
So fügen Sie dem vorhandenen Datenrahmen eine neue Spalte "e" hinzu
quelle
Der Vollständigkeit halber - eine weitere Lösung mit der DataFrame.eval () -Methode:
Daten:
Lösung:
quelle
So erstellen Sie eine leere Spalte
quelle
Folgendes habe ich getan ... Aber ich bin ziemlich neu in Pandas und wirklich Python im Allgemeinen, also keine Versprechen.
quelle
Wenn Sie das erhalten
SettingWithCopyWarning
, besteht eine einfache Lösung darin, den DataFrame zu kopieren, dem Sie eine Spalte hinzufügen möchten.quelle