Ich habe ein Wörterbuch, das so aussieht: di = {1: "A", 2: "B"}
Ich möchte es auf die Spalte "col1" eines Datenrahmens anwenden, ähnlich wie:
col1 col2
0 w a
1 1 2
2 2 NaN
bekommen:
col1 col2
0 w a
1 A 2
2 B NaN
Wie kann ich das am besten machen? Aus irgendeinem Grund zeigt mir das Googeln von Begriffen in diesem Zusammenhang nur Links darüber, wie man Spalten aus Diktaten erstellt und umgekehrt: - /
python
dictionary
pandas
remap
TheChymera
quelle
quelle
col```` is tuple. The error info is
die Typen 'ndarray (dtype = object)' und 'tuple'``` nicht verglichen werden können'3.6.1 |Anaconda custom (64-bit)| (default, May 11 2017, 13:25:24) [MSC v.1900 64 bit (AMD64)]'
map
kann viel schneller sein alsreplace
Wenn Ihr Wörterbuch mehr als ein paar Schlüssel enthält,
map
kann die Verwendung viel schneller sein alsreplace
. Es gibt zwei Versionen dieses Ansatzes, je nachdem, ob Ihr Wörterbuch alle möglichen Werte vollständig abbildet (und ob Sie möchten, dass Nicht-Übereinstimmungen ihre Werte beibehalten oder in NaNs konvertiert werden):Vollständiges Mapping
In diesem Fall ist das Formular sehr einfach:
Obwohl
map
am häufigsten eine Funktion als Argument verwendet wird, kann alternativ ein Wörterbuch oder eine Reihe verwendet werden: Dokumentation für Pandas.series.mapNicht erschöpfendes Mapping
Wenn Sie eine nicht vollständige Zuordnung haben und die vorhandenen Variablen für Nichtübereinstimmungen beibehalten möchten, können Sie Folgendes hinzufügen
fillna
:wie in der Antwort von @ jpp hier: Ersetzen Sie Werte in einer Pandas-Reihe effizient über ein Wörterbuch
Benchmarks
Verwenden der folgenden Daten mit Pandas Version 0.23.1:
und beim Testen mit
%timeit
scheintmap
es ungefähr 10x schneller zu sein alsreplace
.Beachten Sie, dass Ihre Beschleunigung mit
map
mit Ihren Daten variiert. Die größte Beschleunigung scheint bei großen Wörterbüchern und umfassenden Ersetzungen zu liegen. Weitere Informationen zu Benchmarks und Diskussionen finden Sie unter @ jpp-Antwort (oben verlinkt).quelle
df.replace
Funktion war zwar ordentlich und nützlich für kleine Diktate, stürzte jedoch nach etwa 20 Minuten ab.map
arbeitet auch an einem Index, bei dem ich keinen Weg finden konnte, dies zu tunreplace
Ihre Frage ist etwas mehrdeutig. Es gibt mindestens
dreizwei Interpretationen:di
beziehen sich auf Indexwertedi
beziehen sich aufdf['col1']
Wertedi
beziehen sich auf Indexpositionen (nicht die Frage des OP, sondern zum Spaß.).Nachfolgend finden Sie eine Lösung für jeden Fall.
Fall 1: Wenn sich die Schlüssel von
di
auf Indexwerte beziehen sollen, können Sie die folgendeupdate
Methode verwenden:Zum Beispiel,
ergibt
Ich habe die Werte aus Ihrem ursprünglichen Beitrag geändert, damit klarer wird, was zu
update
tun ist. Beachten Sie, wie die Schlüssel indi
mit Indexwerten verknüpft sind. Die Reihenfolge der Indexwerte - , die der Index Standorte - spielt keine Rolle.Fall 2: Wenn sich die Schlüssel in
di
aufdf['col1']
Werte beziehen, zeigen @DanAllan und @DSM, wie dies erreicht werden kann mitreplace
:ergibt
Beachten Sie, wie in diesem Fall die Schlüssel
di
geändert wurden, um den Werten in zu entsprechendf['col1']
.Fall 3: Wenn sich die Schlüssel in
di
auf Indexpositionen beziehen, können Sie sie verwendenschon seit
ergibt
Hier ist die erste und dritte Reihe wurde geändert, da die in Tasten
di
sind0
und2
, die mit Python 0-basierter Indizierung an die ersten und dritte Stelle verweisen.quelle
replace
ist ebenso gut und vielleicht ein besseres Wort für das, was hier passiert.update()
scheint ein wenig klobig im Vergleich zureplace()
, aber zumindest funktioniert es.Hinzufügen zu dieser Frage, wenn Sie jemals mehr als eine Spalte in einem Datendatenrahmen neu zuordnen müssen:
Hoffe, es kann für jemanden nützlich sein.
Prost
quelle
DataFrame.replace()
, obwohl ich nicht weiß, wann sie hinzugefügt wurde.DSM hat die akzeptierte Antwort, aber die Codierung scheint nicht für alle zu funktionieren. Hier ist eine, die mit der aktuellen Version von Pandas funktioniert (0.23.4 ab 8/2018):
Sie werden sehen, es sieht aus wie:
Die Dokumente für pandas.DataFrame.replace finden Sie hier .
quelle
Series.map()
scheint flexibler.Oder machen Sie
apply
:Demo:
quelle
di
Diktat ein Diktat von Listen ist? Wie können Sie nur einen Wert in der Liste zuordnen?Gegeben
map
ist schneller als Ersetzen (@ JohnEs Lösung). Sie müssen bei nicht erschöpfenden ZuordnungenNaN
vorsichtig sein, denen Sie bestimmte Werte zuordnen möchten . Die richtige Methode in diesem Fall erfordert, dass Siemask
die Serie, wenn Sie.fillna
, sonst machen Sie die Zuordnung zu rückgängigNaN
.quelle
Eine schöne Komplettlösung, die eine Karte Ihrer Klassenbezeichnungen enthält:
Auf diese Weise können Sie jederzeit auf die ursprüngliche Klassenbezeichnung von label_dict verweisen.
quelle
Ein nativerer Pandas-Ansatz besteht darin, eine Ersetzungsfunktion wie folgt anzuwenden:
Sobald Sie die Funktion definiert haben, können Sie sie auf Ihren Datenrahmen anwenden.
quelle
Als Erweiterung dessen, was von Nico Coallier (auf mehrere Spalten anwendbar) und U10-Forward (unter Verwendung des Methodenstils "anwenden" vorgeschlagen wurde, und als Zusammenfassung in einem Einzeiler schlage ich vor:
Die
.transform()
verarbeitet jede Spalte als eine Reihe. Im Gegensatz dazu werden.apply()
die in einem DataFrame aggregierten Spalten übergeben.Folglich können Sie die Serienmethode anwenden
map()
.Schließlich, und ich habe dieses Verhalten dank U10 entdeckt, können Sie die gesamte Serie im Ausdruck .get () verwenden. Es sei denn, ich habe sein Verhalten falsch verstanden und es verarbeitet die Serie nacheinander anstatt bitweise.
Die
.get(x,x)
Konten für die Werte, die Sie in Ihrem Mapping-Wörterbuch nicht erwähnt haben und die von der.map()
Methode ansonsten als Nan betrachtet würdenquelle
.transform()
verarbeitet jede Spalte als eine Reihe. Im Gegensatz dazu werden.apply()
die in einem DataFrame aggregierten Spalten übergeben. Ich habe es gerade versucht,apply()
funktioniert gut. Es besteht auch keine Notwendigkeit zu verwendenloc
, dies scheint zu komplex.df[["col1", "col2"]].apply(lambda col: col.map(lambda elem: my_dict.get(elem, elem)))
sollte gut funktionieren. Die.get(x,x)
Konten für die Werte, die Sie in Ihrem Mapping-Wörterbuch nicht erwähnt haben und die ansonsten von der.map()
Methode, die Sie auchfillna()
später verwenden könnten, als Nan betrachtet würden .