Wie kann man in Python Pandas am besten prüfen, ob ein DataFrame einen (oder mehrere) NaN-Werte hat?
Ich kenne die Funktion pd.isnan
, aber dies gibt einen DataFrame von Booleans für jedes Element zurück. Dieser Beitrag hier beantwortet meine Frage auch nicht genau.
Die Antwort von jwilner ist genau richtig. Ich habe nach einer schnelleren Option gesucht, da nach meiner Erfahrung das Summieren von flachen Arrays (merkwürdig) schneller ist als das Zählen. Dieser Code scheint schneller zu sein:
df.isnull().values.any()
Zum Beispiel:
In [2]: df = pd.DataFrame(np.random.randn(1000,1000))
In [3]: df[df > 0.9] = pd.np.nan
In [4]: %timeit df.isnull().any().any()
100 loops, best of 3: 14.7 ms per loop
In [5]: %timeit df.isnull().values.sum()
100 loops, best of 3: 2.15 ms per loop
In [6]: %timeit df.isnull().sum().sum()
100 loops, best of 3: 18 ms per loop
In [7]: %timeit df.isnull().values.any()
1000 loops, best of 3: 948 µs per loop
df.isnull().sum().sum()
ist etwas langsamer, hat aber natürlich zusätzliche Informationen - die Anzahl von NaNs
.
Sie haben mehrere Möglichkeiten.
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(10,6))
# Make a few areas have NaN values
df.iloc[1:3,1] = np.nan
df.iloc[5,3] = np.nan
df.iloc[7:9,5] = np.nan
Nun sieht der Datenrahmen ungefähr so aus:
0 1 2 3 4 5
0 0.520113 0.884000 1.260966 -0.236597 0.312972 -0.196281
1 -0.837552 NaN 0.143017 0.862355 0.346550 0.842952
2 -0.452595 NaN -0.420790 0.456215 1.203459 0.527425
3 0.317503 -0.917042 1.780938 -1.584102 0.432745 0.389797
4 -0.722852 1.704820 -0.113821 -1.466458 0.083002 0.011722
5 -0.622851 -0.251935 -1.498837 NaN 1.098323 0.273814
6 0.329585 0.075312 -0.690209 -3.807924 0.489317 -0.841368
7 -1.123433 -1.187496 1.868894 -2.046456 -0.949718 NaN
8 1.133880 -0.110447 0.050385 -1.158387 0.188222 NaN
9 -0.513741 1.196259 0.704537 0.982395 -0.585040 -1.693810
df.isnull().any().any()
- Dies gibt einen booleschen Wert zurückSie kennen die isnull()
, die einen Datenrahmen wie folgt zurückgeben würde:
0 1 2 3 4 5
0 False False False False False False
1 False True False False False False
2 False True False False False False
3 False False False False False False
4 False False False False False False
5 False False False True False False
6 False False False False False False
7 False False False False False True
8 False False False False False True
9 False False False False False False
Wenn Sie df.isnull().any()
erstellen, finden Sie nur die Spalten mit NaN
-Werten:
0 False
1 True
2 False
3 True
4 False
5 True
dtype: bool
Eine weitere .any()
sagt Ihnen, ob True
> df.isnull().any().any()
True
df.isnull().sum().sum()
- Dies gibt eine ganze Zahl der Gesamtzahl der NaN
-Werte zurück:Dies funktioniert auf die gleiche Weise wie .any().any()
, indem zuerst die Anzahl der NaN
-Werte in einer Spalte summiert wird und dann die Summe dieser Werte:
df.isnull().sum()
0 0
1 2
2 0
3 1
4 0
5 2
dtype: int64
Um die Gesamtzahl der NaN-Werte im DataFrame abzurufen:
df.isnull().sum().sum()
5
Um herauszufinden, welche Zeilen NaNs in einer bestimmten Spalte enthalten:
nan_rows = df[df['name column'].isnull()]
Wenn Sie wissen möchten, wie viele Zeilen mit "einer oder mehreren NaN
s" vorhanden sind:
df.isnull().T.any().T.sum()
Oder wenn Sie diese Zeilen herausziehen und untersuchen müssen:
nan_rows = df[df.isnull().T.any().T]
df.isnull().any().any()
sollte es tun.
Zu Hobs brillanter Antwort fügte ich hinzu, dass ich Python und Pandas noch nicht kennengelernt habe.
Um herauszufinden, welche Zeilen NaNs haben:
nan_rows = df[df.isnull().any(1)]
würde dieselbe Operation ausführen, ohne die Transponierung durchführen zu müssen, indem die Achse von any () als 1 angegeben wird, um zu prüfen, ob in Zeilen "True" vorhanden ist.
Da keine erwähnt wurde, gibt es nur eine weitere Variable namens hasnans
.
df[i].hasnans
wird an True
ausgegeben, wenn einer oder mehrere der Werte in der Pandaserie NaN ist, False
, falls nicht. Beachten Sie, dass es keine Funktion ist.
pandas Version '0.19.2' und '0.20.2'
Da pandas
dies für DataFrame.dropna()
herausfinden muss, schaute ich nach, wie sie es implementieren, und stellte fest, dass sie DataFrame.count()
verwendet haben, das alle Nicht-Null-Werte in der DataFrame
zählt. Vgl. Pandas Quellcode . Ich habe diese Technik nicht bewertet, aber ich schätze, dass die Autoren der Bibliothek wahrscheinlich eine kluge Wahl getroffen haben.
Nur using math.isnan (x) , Rückgabe True, wenn x eine NaN ist (keine Zahl) und sonst False.
Ab v0.23.2 können Sie DataFrame.isna
+ DataFrame.any(axis=None)
verwenden, wobei axis=None
die logische Reduktion über den gesamten DataFrame angibt.
# Setup
df = pd.DataFrame({'A': [1, 2, np.nan], 'B' : [np.nan, 4, 5]})
df
A B
0 1.0 NaN
1 2.0 4.0
2 NaN 5.0
df.isna()
A B
0 False True
1 False False
2 True False
df.isna().any(axis=None)
# True
Eine weitere performante Option, die Sie verwenden können, ist numpy.isnan
:
np.isnan(df.values)
array([[False, True],
[False, False],
[ True, False]])
np.isnan(df.values).any()
# True
Alternativ können Sie die Summe überprüfen:
np.isnan(df.values).sum()
# 2
np.isnan(df.values).sum() > 0
# True
Sie können auch Series.hasnans
iterativ aufrufen. Um beispielsweise zu prüfen, ob eine einzelne Spalte NaNs enthält,
df['A'].hasnans
# True
Um zu prüfen, ob die Spalte any NaNs enthält, können Sie ein Verständnis mit any
verwenden (was eine Kurzschlussoperation ist).
any(df[c].hasnans for c in df)
# True
Dies ist tatsächlich sehr schnell.
Hier ist eine weitere interessante Möglichkeit, Null zu finden und durch einen berechneten Wert zu ersetzen
#Creating the DataFrame
testdf = pd.DataFrame({'Tenure':[1,2,3,4,5],'Monthly':[10,20,30,40,50],'Yearly':[10,40,np.nan,np.nan,250]})
>>> testdf2
Monthly Tenure Yearly
0 10 1 10.0
1 20 2 40.0
2 30 3 NaN
3 40 4 NaN
4 50 5 250.0
#Identifying the rows with empty columns
nan_rows = testdf2[testdf2['Yearly'].isnull()]
>>> nan_rows
Monthly Tenure Yearly
2 30 3 NaN
3 40 4 NaN
#Getting the rows# into a list
>>> index = list(nan_rows.index)
>>> index
[2, 3]
# Replacing null values with calculated value
>>> for i in index:
testdf2['Yearly'][i] = testdf2['Monthly'][i] * testdf2['Tenure'][i]
>>> testdf2
Monthly Tenure Yearly
0 10 1 10.0
1 20 2 40.0
2 30 3 90.0
3 40 4 160.0
4 50 5 250.0
Oder Sie können .info()
für die DF
verwenden, zum Beispiel:
df.info(null_counts=True)
gibt die Anzahl der non_null-Zeilen in einer Spalte zurück, z.
<class 'pandas.core.frame.DataFrame'>
Int64Index: 3276314 entries, 0 to 3276313
Data columns (total 10 columns):
n_matches 3276314 non-null int64
avg_pic_distance 3276314 non-null float64
sei df
der Name des Pandas DataFrame und jeder Wert, der numpy.nan
ist, ist ein Nullwert.
df.isnull().any()
df.loc[:, df.isnull().any()].columns
df.loc[:, list(df.loc[:, df.isnull().any()].columns)].isnull().sum()
df.loc[:,list(df.loc[:,df.isnull().any()].columns)].isnull().sum()/(len(df))*100
EDIT 1: Wenn Sie sehen möchten, wo Ihre Daten visuell fehlen:import missingno
missingdata_df = df.columns[df.isnull().any()].tolist()
missingno.matrix(df[missingdata_df])
Ich habe Folgendes verwendet und es in einen String umgewandelt und nach dem Nan-Wert gesucht
(str(df.at[index, 'column']) == 'nan')
Auf diese Weise kann ich einen bestimmten Wert in einer Reihe überprüfen und nicht nur zurückgeben, wenn dieser irgendwo in der Reihe enthalten ist.
Am besten verwenden Sie:
df.isna().any().any()
Hier ist warum . isna()
wird also verwendet, um isnull()
zu definieren, aber beide sind natürlich identisch.
Dies ist sogar schneller als die akzeptierte Antwort und deckt alle 2D-Panda-Arrays ab.
df.isnull (). sum () Hiermit können Sie alle NaN-Werte im DataFrame zählen
df.apply(axis=0, func=lambda x : any(pd.isnull(x)))
Überprüft für jede Spalte, ob sie Nan enthält oder nicht.
Abhängig von der Art der Daten, mit denen Sie es zu tun haben, können Sie während der Durchführung Ihrer EDA auch einfach die Werte für jede Spalte ermitteln, indem Sie dropna auf False setzen.
for col in df:
print df[col].value_counts(dropna=False)
Funktioniert gut für kategoriale Variablen, nicht so sehr, wenn Sie viele eindeutige Werte haben.