W Pythonie Pandas jaki jest najlepszy sposób sprawdzenia, czy DataFrame ma jedną (lub więcej) wartości NaN?
Wiem o tej funkcji pd.isnan, ale zwraca DataFrame booleans dla każdego elementu. Ten post tutaj również nie odpowiada na moje pytanie.
W Pythonie Pandas jaki jest najlepszy sposób sprawdzenia, czy DataFrame ma jedną (lub więcej) wartości NaN?
Wiem o tej funkcji pd.isnan, ale zwraca DataFrame booleans dla każdego elementu. Ten post tutaj również nie odpowiada na moje pytanie.
Odpowiedzi:
Odpowiedź jwilnera jest natychmiastowa. Badałem, czy jest szybsza opcja, ponieważ z mojego doświadczenia, sumowanie płaskich tablic jest (dziwnie) szybsze niż liczenie. Ten kod wydaje się szybszy:
df.isnull().values.any()
Na przykład:
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()jest nieco wolniejszy, ale oczywiście ma dodatkowe informacje - liczbę NaNs.
pandasnie ma do tego wbudowanej funkcji. To prawda, że post @ JGreenwell df.describe()może to zrobić, ale nie ma bezpośredniej funkcji.
df.describe()(bez znalezienia NaNs). W przypadku tablicy 1000 x 1000 pojedyncze połączenie zajmuje 1,15 sekundy.
df.isnull().values.sum()jest nieco szybszy niżdf.isnull().values.flatten().sum()
.flatten()plakatu. Dzięki.
df.isnull().values.any(), dla mnie jest szybszy niż inni.
Masz kilka opcji.
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
Teraz ramka danych wygląda mniej więcej tak:
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()- Zwraca wartość logicznąWiesz o tym, isnull()która zwróciłaby ramkę danych taką jak ta:
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
Jeśli to zrobisz df.isnull().any(), możesz znaleźć tylko kolumny, które mają NaNwartości:
0 False
1 True
2 False
3 True
4 False
5 True
dtype: bool
Jeszcze jeden .any()powie ci, czy którykolwiek z powyższych jestTrue
> df.isnull().any().any()
True
df.isnull().sum().sum()- Zwraca liczbę całkowitą całkowitej liczby NaNwartości:Działa to w ten sam sposób, co .any().any()robi, najpierw podając sumę liczby NaNwartości w kolumnie, a następnie sumując te wartości:
df.isnull().sum()
0 0
1 2
2 0
3 1
4 0
5 2
dtype: int64
Wreszcie, aby uzyskać całkowitą liczbę wartości NaN w DataFrame:
df.isnull().sum().sum()
5
.any(axis=None)zamiast .any().any()?
Aby dowiedzieć się, które wiersze zawierają NaN w określonej kolumnie:
nan_rows = df[df['name column'].isnull()]
non_nan_rows = df[df['name column'].notnull()].
Jeśli chcesz wiedzieć, ile wierszy zawiera „jeden lub więcej NaNs”:
df.isnull().T.any().T.sum()
Lub jeśli musisz wyciągnąć te rzędy i zbadać je:
nan_rows = df[df.isnull().T.any().T]
Dodając do płyty genialną odpowiedź, jestem zupełnie nowy w Pythonie i Pandach, więc proszę wskazać, czy się mylę.
Aby dowiedzieć się, które wiersze mają NaN:
nan_rows = df[df.isnull().any(1)]
wykonałby tę samą operację bez potrzeby transponowania, określając oś dowolnej () jako 1, aby sprawdzić, czy w wierszach występuje „prawda”.
any(axis=1)uproszczenie.
df.isna().any(axis=None)Począwszy od wersji 0.23.2 , można użyć DataFrame.isna+, DataFrame.any(axis=None)gdzie axis=Noneokreśla logiczną redukcję w całej ramce danych.
# 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
numpy.isnan
Kolejna wydajna opcja, jeśli korzystasz ze starszych wersji pand.
np.isnan(df.values)
array([[False, True],
[False, False],
[ True, False]])
np.isnan(df.values).any()
# True
Ewentualnie sprawdź sumę:
np.isnan(df.values).sum()
# 2
np.isnan(df.values).sum() > 0
# True
Series.hasnans
Możesz także iteracyjnie zadzwonić Series.hasnans. Na przykład, aby sprawdzić, czy pojedyncza kolumna ma NaN,
df['A'].hasnans
# True
Aby sprawdzić, czy jakakolwiek kolumna ma NaN, możesz skorzystać ze zrozumienia any(co jest operacją zwarcia).
any(df[c].hasnans for c in df)
# True
To jest naprawdę bardzo szybkie.
Ponieważ żaden z nich nie wspomniał, istnieje tylko jedna zmienna o nazwie hasnans .
df[i].hasnanswyświetli się, Truejeśli jedna lub więcej wartości w serii pand to NaN,False jeśli nie. Zauważ, że to nie jest funkcja.
wersja pandy „0.19.2” i „0.20.2”
df = DataFrame([1,None], columns=['foo']), to df.hasnansrzuci AttributeError, ale df.foo.hasnanswróci True.
Ponieważ muszę pandassię tego dowiedzieć DataFrame.dropna(), przyjrzałem się, jak to zaimplementowali, i odkryłem, że skorzystali DataFrame.count(), co zlicza wszystkie wartości inne niż null w DataFrame. Por. kod źródłowy pandy . Nie przeprowadziłem testów porównawczych tej techniki, ale sądzę, że autorzy biblioteki prawdopodobnie dokonali mądrego wyboru.
niech dfbędzie nazwą Pandas DataFrame i dowolną wartością, która jest numpy.nanwartością zerową.
df.isnull().any()df.loc[:, df.isnull().any()].columnsdf.isna().sum()Jeśli chcesz zobaczyć procent zerowych wartości w każdej kolumnie
df.isna().sum()/(len(df))*100df.loc[:,list(df.loc[:,df.isnull().any()].columns)].isnull().sum()/(len(df))*100EDYCJA 1:
Jeśli chcesz zobaczyć, gdzie brakuje danych:
import missingno
missingdata_df = df.columns[df.isnull().any()].tolist()
missingno.matrix(df[missingdata_df])
df.isna().sum()?
Wystarczy użyć math.isnan (x) , Zwróć True, jeśli x jest NaN (nie liczbą), a False inaczej.
math.isnan(x)zadziała, gdy xjest ramką DataFrame. Zamiast tego otrzymasz TypeError.
df.isnull().sum()
To da ci zliczenie wszystkich wartości NaN obecnych w odpowiednich kolorach DataFrame.
Oto kolejny interesujący sposób znalezienia wartości null i zastąpienia jej wartością obliczoną
#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
Korzystałem z następujących i wpisz rzut casting na ciąg i sprawdzanie wartości nan
(str(df.at[index, 'column']) == 'nan')
To pozwala mi sprawdzić określoną wartość w serii, a nie tylko zwrócić, jeśli jest ona zawarta gdzieś w serii.
pandas.isna()?
Lub możesz użyć .info()na DFtakich jak:
df.info(null_counts=True) która zwraca liczbę niepustych wierszy w kolumnach takich jak:
<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
df.apply(axis=0, func=lambda x : any(pd.isnull(x)))
Sprawdza dla każdej kolumny, czy zawiera Nan, czy nie.
Widzimy prezent wartości null w zbiorze danych poprzez generowanie mapę cieplną przy użyciu modułu Seaborn mapę cieplną
import pandas as pd
import seaborn as sns
dataset=pd.read_csv('train.csv')
sns.heatmap(dataset.isnull(),cbar=False)
Możesz nie tylko sprawdzić, czy istnieje jakikolwiek „NaN”, ale także uzyskać procent „NaN” w każdej kolumnie, stosując następujące informacje,
df = pd.DataFrame({'col1':[1,2,3,4,5],'col2':[6,np.nan,8,9,10]})
df
col1 col2
0 1 6.0
1 2 NaN
2 3 8.0
3 4 9.0
4 5 10.0
df.isnull().sum()/len(df)
col1 0.0
col2 0.2
dtype: float64
W zależności od rodzaju danych, z którymi masz do czynienia, możesz również uzyskać zliczenia wartości każdej kolumny podczas wykonywania EDA, ustawiając dropna na False.
for col in df:
print df[col].value_counts(dropna=False)
Działa dobrze dla zmiennych jakościowych, nie tak bardzo, gdy masz wiele unikalnych wartości.