Pandas Datenrahmen fillna () nur einige Spalten vorhanden

144

Ich versuche, keine Werte in einem Pandas-Datenrahmen mit Nullen für nur eine Teilmenge von Spalten zu füllen.

Wenn ich es tue:

import pandas as pd
df = pd.DataFrame(data={'a':[1,2,3,None],'b':[4,5,None,6],'c':[None,None,7,8]})
print df
df.fillna(value=0, inplace=True)
print df

Die Ausgabe:

     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  NaN  7.0
3  NaN  6.0  8.0
     a    b    c
0  1.0  4.0  0.0
1  2.0  5.0  0.0
2  3.0  0.0  7.0
3  0.0  6.0  8.0

Es ersetzt jedes Nonedurch 0's. Was ich tun möchte, ist, nur Nones in Spalten zu ersetzen aund b, aber nicht c.

Was ist der beste Weg, dies zu tun?

Sait
quelle

Antworten:

218

Sie können Ihre gewünschten Spalten auswählen und dies durch Zuweisung tun:

df[['a', 'b']] = df[['a','b']].fillna(value=0)

Die resultierende Ausgabe ist wie erwartet:

     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  0.0  7.0
3  0.0  6.0  8.0
Wurzel
quelle
Ja, genau das will ich! Danke dir. Gibt es Möglichkeiten, dies an Ort und Stelle zu tun? Mein ursprünglicher Datenrahmen ist ziemlich groß.
Sait
1
Ich glaube nicht, dass es einen Leistungsgewinn gibt, wenn Sie dies tun, da Sie den orig df sowieso überschreiben
EdChum
4
Die Lok ist hier überflüssig, df[['a', 'b']] = df[['a','b']].fillna(value=0)wird noch funktionieren
EdChum
2
@EdChum Erzeugt es keinen temporären Datenrahmen und benötigt dazu mehr Speicher? (Ich mache mir mehr Sorgen um das Gedächtnis als um die Komplexität der Zeit.)
Sait
7
Bei vielen Vorgängen inplacewird weiterhin an einer Kopie gearbeitet. Ich weiß nicht, ob das der Fall ist fillnaoder nicht. Siehe diese Antwort von einem der Pandas-Kernentwickler.
Wurzel
84

Sie können unter Verwendung von dict, fillnamit anderem Wert für verschiedene Spalt

df.fillna({'a':0,'b':0})
Out[829]: 
     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  0.0  7.0
3  0.0  6.0  8.0

Nachdem Sie es zurück zugewiesen haben

df=df.fillna({'a':0,'b':0})
df
Out[831]: 
     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  0.0  7.0
3  0.0  6.0  8.0
YOBEN_S
quelle
1
wirklich cool, übrigens für das Diktat, das Sie verwenden können, fromkeyswenn Sie wollen, +1
U10-Forward
1
Die Antwort / das Beispiel wäre klarer, wenn tatsächlich unterschiedliche Werte für die verschiedenen Spalten angezeigt würden.
RufusVS
@ RufusVS das ist richtig, aber immer noch versuchen, die erwartete Ausgabe der
Operation zu entsprechen
1
Dies ist die bessere Lösung als die akzeptierte Antwort, da verkettete Indexierungsprobleme vermieden werden, z. B. wenn sie mitdf.fillna({'a':0,'b':0}, inplace=True)
Alex
19

Sie können vermeiden, eine Kopie des Objekts mit Wens Lösung zu erstellen, und inplace = True:

df.fillna({'a':0, 'b':0}, inplace=True)
print(df)

Welche Ausbeuten:

     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  0.0  7.0
3  0.0  6.0  8.0
Leesa H.
quelle
1
Obwohl dies korrekt ist, ist das Vermeiden einer Kopie nicht unbedingt besser .
Jpp
7

So können Sie alles in einer Zeile erledigen:

df[['a', 'b']].fillna(value=0, inplace=True)

Aufschlüsselung: df[['a', 'b']]Wählt die Spalten aus, für die Sie NaN-Werte value=0füllen möchten , weist sie an, NaNs mit Null zu füllen, und inplace=Truemacht die Änderungen dauerhaft, ohne dass eine Kopie des Objekts erstellt werden muss.

Josephine M. Ho
quelle
7

Wenn Sie die oberste Antwort verwenden, wird eine Warnung angezeigt, dass Änderungen an einer Kopie eines df-Slice vorgenommen werden. Angenommen, Sie haben andere Spalten, ist es besser, ein Wörterbuch zu übergeben:
df.fillna({'A': 'NA', 'B': 'NA'}, inplace=True)

Jonathan
quelle
3

Oder so etwas wie:

df.loc[df['a'].isnull(),'a']=0
df.loc[df['b'].isnull(),'b']=0

und wenn es mehr gibt:

for i in your_list:
    df.loc[df[i].isnull(),i]=0
U10-Vorwärts
quelle
0

Manchmal funktioniert diese Syntax nicht:

df[['col1','col2']] = df[['col1','col2']].fillna()

Verwenden Sie stattdessen Folgendes:

df['col1','col2']
Sarath Baby
quelle