Wie kann ich alle NaN-Werte durch Nullen in einer Spalte eines Pandas-Datenrahmens ersetzen?


457

Ich habe einen Datenrahmen wie unten

      itm Date                  Amount 
67    420 2012-09-30 00:00:00   65211
68    421 2012-09-09 00:00:00   29424
69    421 2012-09-16 00:00:00   29877
70    421 2012-09-23 00:00:00   30990
71    421 2012-09-30 00:00:00   61303
72    485 2012-09-09 00:00:00   71781
73    485 2012-09-16 00:00:00     NaN
74    485 2012-09-23 00:00:00   11072
75    485 2012-09-30 00:00:00  113702
76    489 2012-09-09 00:00:00   64731
77    489 2012-09-16 00:00:00     NaN

Wenn ich versuche, eine Funktion auf die Spalte Betrag anzuwenden, wird der folgende Fehler angezeigt.

ValueError: cannot convert float NaN to integer

Ich habe versucht, eine Funktion mit .isnan aus dem Mathematikmodul anzuwenden. Ich habe das pandas .replace-Attribut ausprobiert. Ich habe das .sparse-Datenattribut aus pandas 0.9 ausprobiert. Ich habe auch versucht, ob NaN == NaN-Anweisung in einer Funktion. Ich habe mir auch diesen Artikel angesehen. Wie ersetze ich NA-Werte in einem R-Datenrahmen durch Nullen? beim Betrachten einiger anderer Artikel. Alle Methoden, die ich ausprobiert habe, haben nicht funktioniert oder erkennen NaN nicht. Alle Hinweise oder Lösungen wäre dankbar.


Das einzige Problem ist, dass df.fill.na () nicht funktioniert, wenn der Datenrahmen, auf den Sie ihn anwenden, erneut abgetastet wird oder durch die loc-Funktion geschnitten wurde
Prince Agarwal

Antworten:


754

Ich glaube, das DataFrame.fillna()wird das für dich tun.

Link zu Dokumenten für einen Datenrahmen und für eine Serie .

Beispiel:

In [7]: df
Out[7]: 
          0         1
0       NaN       NaN
1 -0.494375  0.570994
2       NaN       NaN
3  1.876360 -0.229738
4       NaN       NaN

In [8]: df.fillna(0)
Out[8]: 
          0         1
0  0.000000  0.000000
1 -0.494375  0.570994
2  0.000000  0.000000
3  1.876360 -0.229738
4  0.000000  0.000000

Um die NaNs nur in eine Spalte zu füllen, wählen Sie nur diese Spalte aus. In diesem Fall verwende ich inplace = True, um den Inhalt von df tatsächlich zu ändern.

In [12]: df[1].fillna(0, inplace=True)
Out[12]: 
0    0.000000
1    0.570994
2    0.000000
3   -0.229738
4    0.000000
Name: 1

In [13]: df
Out[13]: 
          0         1
0       NaN  0.000000
1 -0.494375  0.570994
2       NaN  0.000000
3  1.876360 -0.229738
4       NaN  0.000000

BEARBEITEN:

Um a zu vermeiden SettingWithCopyWarning, verwenden Sie die integrierte spaltenspezifische Funktionalität:

df.fillna({1:0}, inplace=True)

1
Ist garantiert, dass df[1]es sich eher um eine Ansicht als um eine Kopie des Original-DF handelt? Wenn es eine seltene Situation gibt, in der es sich um eine Kopie handelt, würde dies natürlich einen äußerst problematischen Fehler verursachen. Gibt es dazu eine klare Aussage in der Pandas-Dokumentation?
Max

@max Sehen Sie dies, könnte Ihre Frage beantworten: stackoverflow.com/questions/23296282/…
Aman

Vielen Dank. Ist mein Verständnis richtig, dass in dieser Antwort ein "Indexer, der setzt" die äußerste Indizierungsoperation ist (die unmittelbar vor der Zuweisung ausgeführt wird. Jede Zuweisung, die nur einen einzelnen Indexer verwendet, ist also garantiert sicher, wodurch Ihr Code sicher wird?
max.

1
Warum funktioniert das bei mir nicht? siehe: stackoverflow.com/questions/39452095/how-to-fillna-with-value-0
Anzeigename

1
Das letzte Beispiel wirft eine SettingWithCopyWarning
Sip

124

Es kann nicht garantiert werden, dass das Schneiden eine Ansicht oder eine Kopie zurückgibt. Du kannst tun

df['column'] = df['column'].fillna(value)

14
Habe gerade das Problem "inplace = True" entdeckt. Diese Antwort vermeidet das Problem und ich denke, es ist die sauberste Lösung, die vorgestellt wird.
TimCera

48

Sie könnten verwenden replaceändern NaNzu 0:

import pandas as pd
import numpy as np

# for column
df['column'] = df['column'].replace(np.nan, 0)

# for whole dataframe
df = df.replace(np.nan, 0)

# inplace
df.replace(np.nan, 0, inplace=True)

Wird es nur ersetzen NaN? oder wird es auch den Wert ersetzen, wo NAoder NaNwie df.fillna(0)? Ich suche nach einer Lösung, die den Wert nur dort ersetzt, wo er ist NaNund nichtNA
Shyam Bhimani

1
@ShyamBhimani es sollte nur NaNdh Werte ersetzen , wo np.isnanwahr ist
Anton Protopopov

23

Ich wollte nur ein bisschen ein Update / einen Sonderfall bereitstellen, da es so aussieht, als ob die Leute immer noch hierher kommen. Wenn Sie einen Multi-Index oder einen Index-Slicer verwenden, reicht die Option inplace = True möglicherweise nicht aus, um das ausgewählte Slice zu aktualisieren. In einem 2x2-Level-Multi-Index ändert dies beispielsweise keine Werte (ab Pandas 0.15):

idx = pd.IndexSlice
df.loc[idx[:,mask_1],idx[mask_2,:]].fillna(value=0,inplace=True)

Das "Problem" besteht darin, dass die Verkettung die Fillna-Fähigkeit zum Aktualisieren des ursprünglichen Datenrahmens unterbricht. Ich habe "Problem" in Anführungszeichen gesetzt, weil es gute Gründe für die Entwurfsentscheidungen gibt, die in bestimmten Situationen dazu geführt haben, dass diese Ketten nicht interpretiert wurden. Dies ist auch ein komplexes Beispiel (obwohl ich wirklich darauf gestoßen bin), aber das Gleiche gilt möglicherweise für weniger Indexebenen, je nachdem, wie Sie schneiden.

Die Lösung lautet DataFrame.update:

df.update(df.loc[idx[:,mask_1],idx[[mask_2],:]].fillna(value=0))

Es ist eine Zeile, liest sich ziemlich gut (Art) und eliminiert unnötiges Durcheinander mit Zwischenvariablen oder Schleifen, während Sie Fillna auf jedes mehrstufige Slice anwenden können, das Sie mögen!

Wenn jemand Orte finden kann, an denen dies nicht funktioniert, posten Sie dies bitte in den Kommentaren. Ich habe damit herumgespielt und mir die Quelle angesehen, und es scheint zumindest meine Multi-Index-Slice-Probleme zu lösen.


21

Der folgende Code hat bei mir funktioniert.

import pandas

df = pandas.read_csv('somefile.txt')

df = df.fillna(0)

7

Einfache Möglichkeit, die fehlenden Werte zu füllen: -

Füllen von Zeichenfolgenspalten: Wenn Zeichenfolgenspalten fehlende Werte und NaN-Werte aufweisen.

df['string column name'].fillna(df['string column name'].mode().values[0], inplace = True)

Füllen von numerischen Spalten: Wenn die numerischen Spalten fehlende Werte und NaN-Werte haben.

df['numeric column name'].fillna(df['numeric column name'].mean(), inplace = True)

NaN mit Null füllen:

df['column name'].fillna(0, inplace = True)

5

Sie können auch Wörterbücher verwenden, um NaN-Werte der spezifischen Spalten im DataFrame zu füllen, anstatt alle DF mit einem Wert zu füllen.

import pandas as pd

df = pd.read_excel('example.xlsx')
df.fillna( {
        'column1': 'Write your values here',
        'column2': 'Write your values here',
        'column3': 'Write your values here',
        'column4': 'Write your values here',
        .
        .
        .
        'column-n': 'Write your values here'} , inplace=True)

Dies ist die vom Entwickler beabsichtigte Lösung für die Frage des OP.
JohnDanger

4

Geben Sie hier die Bildbeschreibung ein

In Anbetracht der bestimmten Spalte Amountin der obigen Tabelle handelt es sich um einen ganzzahligen Typ. Folgendes wäre eine Lösung:

df['Amount'] = df.Amount.fillna(0).astype(int)

In ähnlicher Weise können Sie es mit verschiedenen Datentypen wie füllen float, strund so weiter.

Insbesondere würde ich den Datentyp in Betracht ziehen, um verschiedene Werte derselben Spalte zu vergleichen.


2

Na-Werte in Pandas ersetzen

df['column_name'].fillna(value_to_be_replaced,inplace=True)

Wenn inplace = Falseder df (Datenrahmen) nicht aktualisiert wird, werden die geänderten Werte zurückgegeben.


1

Wenn Sie es in einen Pandas-Datenrahmen konvertieren, können Sie dies auch mithilfe von erreichen fillna.

import numpy as np
df=np.array([[1,2,3, np.nan]])

import pandas as pd
df=pd.DataFrame(df)
df.fillna(0)

Dies gibt Folgendes zurück:

     0    1    2   3
0  1.0  2.0  3.0 NaN
>>> df.fillna(0)
     0    1    2    3
0  1.0  2.0  3.0  0.0

1

In erster Linie stehen zwei Optionen zur Verfügung. im Falle der Imputation oder des Füllens fehlender Werte NaN / np.nan mit nur numerischen Ersetzungen (über Spalte (n) hinweg:

df['Amount'].fillna(value=None, method= ,axis=1,) ist ausreichend:

Aus der Dokumentation:

Wert: Skalar, Diktat, Serie oder DataFrame Wert zum Füllen von Löchern (z. B. 0), alternativ ein Diktat / Serie / DataFrame mit Werten, die angeben, welcher Wert für jeden Index (für eine Serie) oder Spalte (für einen DataFrame) verwendet werden soll. . (Werte, die nicht im Diktat / Serie / Datenrahmen enthalten sind, werden nicht gefüllt). Dieser Wert kann keine Liste sein.

Das heißt, "Strings" oder "Konstanten" dürfen nicht mehr unterstellt werden.

Verwenden Sie für speziellere Imputationen SimpleImputer () :

from sklearn.impute import SimpleImputer
si = SimpleImputer(strategy='constant', missing_values=np.nan, fill_value='Replacement_Value')
df[['Col-1', 'Col-2']] = si.fit_transform(X=df[['C-1', 'C-2']])

0

So ersetzen Sie Nan in verschiedenen Spalten auf unterschiedliche Weise:

   replacement= {'column_A': 0, 'column_B': -999, 'column_C': -99999}
   df.fillna(value=replacement)
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.