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?

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

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

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

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.


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)


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

0

Manchmal funktioniert diese Syntax nicht:

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

Verwenden Sie stattdessen Folgendes:

df['col1','col2']
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.