Ersetzen von Spaltenwerten in einem Pandas DataFrame

141

Ich versuche, die Werte in einer Spalte eines Datenrahmens zu ersetzen. Die Spalte ('weiblich') enthält nur die Werte 'weiblich' und 'männlich'.

Ich habe folgendes versucht:

w['female']['female']='1'
w['female']['male']='0' 

Erhalten Sie jedoch genau die gleiche Kopie der vorherigen Ergebnisse.

Idealerweise möchte ich eine Ausgabe erhalten, die der folgenden Schleife elementweise ähnelt.

if w['female'] =='female':
    w['female'] = '1';
else:
    w['female'] = '0';

Ich habe die Gotchas-Dokumentation ( http://pandas.pydata.org/pandas-docs/stable/gotchas.html ) durchgesehen , kann aber nicht herausfinden, warum nichts passiert.

Jede Hilfe wird geschätzt.

Schwarz
quelle

Antworten:

258

Wenn ich richtig verstehe, möchten Sie so etwas:

w['female'] = w['female'].map({'female': 1, 'male': 0})

(Hier konvertiere ich die Werte in Zahlen anstelle von Zeichenfolgen, die Zahlen enthalten. Sie können sie in "1"und konvertieren "0", wenn Sie wirklich wollen, aber ich bin mir nicht sicher, warum Sie das wollen.)

Der Grund, warum Ihr Code nicht funktioniert, liegt darin, dass die Verwendung ['female']für eine Spalte (die zweite 'female'in Ihrer w['female']['female']) nicht "Zeilen auswählen, bei denen der Wert" weiblich "ist" bedeutet. Dies bedeutet, dass Sie Zeilen auswählen, in denen der Index "weiblich" ist, von denen möglicherweise keine in Ihrem DataFrame vorhanden sind.

BrenBarn
quelle
6
Vielen Dank. Genau das, wonach ich gesucht habe. Wenn ich 'weiblich' auf 1 und alles andere auf '0' abbilden würde. Wie würde das funktionieren?
Schwarz
17
Verwenden Sie diese Option nur, wenn alle Werte in der Spalte in der Kartenfunktion angegeben sind. Spaltenwerte, die nicht in der Kartenfunktion angegeben sind, werden durch nan ersetzt.
Chandra
1
Ich würde auch empfehlen, die .locSyntax zu verwenden, um Folgendes zu vermeiden SettingWithCopyWarning: pandas.pydata.org/pandas-docs/stable/…
NickBraunagel
2
anstelle von .map habe ich .replace
JS noob
Wie werde ich das '.' von den Tausenden auf zwei oder mehr Spalten kann nicht herausfinden. Vielen Dank
M. Mariscal
115

Sie können eine Teilmenge eines Datenrahmens mit loc bearbeiten:

df.loc[<row selection>, <column selection>]

In diesem Fall:

w.loc[w.female != 'female', 'female'] = 0
w.loc[w.female == 'female', 'female'] = 1
Jimmy Petersson
quelle
1
Wie würde ich es anpassen, damit ich nicht bestimmte Zeilen über eine Bedingung auswählen muss, sondern nur alle Zeilen in einer bestimmten Spalte? Ändern Sie also alle Zellen in einer Spalte auf einen bestimmten Wert.
Dhruv Ghulati
3
@DhruvGhulati, würden Sie df.loc [:, <Spaltenauswahl>]
38

Leichte Variation:

w.female.replace(['male', 'female'], [1, 0], inplace=True)
Deckard
quelle
19

Dies sollte auch funktionieren:

w.female[w.female == 'female'] = 1 
w.female[w.female == 'male']   = 0
Nick Crawford
quelle
11

Sie können auch applymit .getdh verwenden

w['female'] = w['female'].apply({'male':0, 'female':1}.get)::

w = pd.DataFrame({'female':['female','male','female']})
print(w)

Datenrahmen w:

   female
0  female
1    male
2  female

Verwenden applyzum Ersetzen von Werten aus dem Wörterbuch:

w['female'] = w['female'].apply({'male':0, 'female':1}.get)
print(w)

Ergebnis:

   female
0       1
1       0
2       1 

Hinweis: apply Mit Wörterbuch sollte verwendet werden, wenn alle möglichen Werte der Spalten im Datenrahmen im Wörterbuch definiert sind. Andernfalls ist es leer für diejenigen, die nicht im Wörterbuch definiert sind.

Student
quelle
8

Das ist sehr kompakt:

w['female'][w['female'] == 'female']=1
w['female'][w['female'] == 'male']=0

Ein weiterer guter:

w['female'] = w['female'].replace(regex='female', value=1)
w['female'] = w['female'].replace(regex='male', value=0)
Azz
quelle
Das erste Beispiel ist eine verkettete Indizierung und wird davor gewarnt, da es nicht garantieren kann, ob das resultierende df eine Kopie oder eine Ansicht ist. Siehe Chained-Indexing
Nordle
7

Alternativ gibt es die integrierte Funktion pd.get_dummies für diese Art von Zuweisungen:

w['female'] = pd.get_dummies(w['female'],drop_first = True)

Dies gibt Ihnen einen Datenrahmen mit zwei Spalten, eine für jeden Wert, der in w ['weiblich'] vorkommt, von dem Sie den ersten löschen (weil Sie ihn aus der verbleibenden ableiten können). Die neue Spalte wird automatisch als die Zeichenfolge benannt, die Sie ersetzt haben.

Dies ist besonders nützlich, wenn Sie kategoriale Variablen mit mehr als zwei möglichen Werten haben. Diese Funktion erstellt so viele Dummy-Variablen, wie zur Unterscheidung aller Fälle erforderlich sind. Achten Sie dann darauf, dass Sie nicht den gesamten Datenrahmen einer einzelnen Spalte zuweisen, sondern, wenn w ['weiblich'] 'männlich', 'weiblich' oder 'neutral' sein könnte, Folgendes tun:

w = pd.concat([w, pd.get_dummies(w['female'], drop_first = True)], axis = 1])
w.drop('female', axis = 1, inplace = True)

Dann bleiben Ihnen zwei neue Spalten, die Ihnen die Dummy-Codierung von 'weiblich' geben, und Sie haben die Spalte mit den Zeichenfolgen entfernt.

Galliwuzz
quelle
4

Verwenden Series.mapmitSeries.fillna

Wenn Ihre Spalte mehr Zeichenfolgen als nur femaleund enthält male, Series.mapschlägt dies in diesem Fall fehl, da NaNandere Werte zurückgegeben werden.

Deshalb müssen wir es verketten mit fillna:

Beispiel, warum .mapfehlschlägt :

df = pd.DataFrame({'female':['male', 'female', 'female', 'male', 'other', 'other']})

   female
0    male
1  female
2  female
3    male
4   other
5   other
df['female'].map({'female': '1', 'male': '0'})

0      0
1      1
2      1
3      0
4    NaN
5    NaN
Name: female, dtype: object

Für die richtige Methode verketten wir mapmit fillna, also füllen wir die NaNmit Werten aus der ursprünglichen Spalte:

df['female'].map({'female': '1', 'male': '0'}).fillna(df['female'])

0        0
1        1
2        1
3        0
4    other
5    other
Name: female, dtype: object
Erfan
quelle
2

Es gibt auch eine pandasaufgerufene Funktion, mit factorizeder Sie diese Art von Arbeit automatisch ausführen können. Es konvertiert Beschriftungen in Zahlen : ['male', 'female', 'male'] -> [0, 1, 0]. Weitere Informationen finden Sie in dieser Antwort.

Roald
quelle
0

Ich denke, als Antwort sollte darauf hingewiesen werden, welchen Objekttyp Sie in allen oben vorgeschlagenen Methoden erhalten: Ist es Serie oder DataFrame?

Wenn Sie eine Spalte von w.female.oder erhalten w[[2]](wobei 2 die Nummer Ihrer Spalte ist), erhalten Sie DataFrame zurück. In diesem Fall können Sie also DataFrame-Methoden wie verwenden .replace.

Wenn Sie .locoder ilocSie Series zurück und Serie hat keine .replaceMethode, so dass Sie Methoden wie verwenden sollten apply, mapund so weiter.

Alex-Droide AD
quelle