Cara memeriksa apakah ada nilai yang NaN dalam DataFrame Pandas


Jawaban:


578

Tanggapan jwilner tepat. Saya sedang mengeksplorasi untuk melihat apakah ada opsi yang lebih cepat, karena dalam pengalaman saya, menjumlahkan array datar (anehnya) lebih cepat daripada menghitung. Kode ini tampaknya lebih cepat:

df.isnull().values.any()

Sebagai contoh:

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()sedikit lebih lambat, tetapi tentu saja, memiliki informasi tambahan - jumlahnya NaNs.


1
Terima kasih atas tolok ukur waktu. Mengejutkan bahwa pandastidak memiliki fungsi bawaan untuk ini. Memang benar dari pos @ JGreenwell yang df.describe()dapat melakukan ini, tetapi tidak ada fungsi langsung.
hlin117

2
Saya hanya menghitung waktu df.describe()(tanpa menemukan NaN). Dengan array 1000 x 1000, satu panggilan membutuhkan waktu 1,15 detik.
hlin117

3
: 1, Juga, df.isnull().values.sum()sedikit lebih cepat daridf.isnull().values.flatten().sum()
Nol

Ah, tangkapan yang bagus @JohnGalt - Saya akan mengubah solusi saya untuk menghapus .flatten()postering. Terima kasih.
S Anand

6
Anda tidak mencoba df.isnull().values.any(), bagi saya itu lebih cepat daripada yang lain.
CK1

178

Anda memiliki dua pilihan.

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

Sekarang bingkai data terlihat seperti ini:

          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
  • Opsi 1 : df.isnull().any().any()- Ini mengembalikan nilai boolean

Anda tahu isnull()yang akan mengembalikan bingkai data seperti ini:

       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

Jika berhasil df.isnull().any(), Anda dapat menemukan kolom yang memiliki NaNnilai:

0    False
1     True
2    False
3     True
4    False
5     True
dtype: bool

Satu lagi .any()akan memberi tahu Anda jika ada di atasTrue

> df.isnull().any().any()
True
  • Opsi 2 : df.isnull().sum().sum()- Ini mengembalikan bilangan bulat dari jumlah total NaNnilai:

Ini beroperasi dengan cara yang sama seperti yang .any().any()dilakukan, dengan terlebih dahulu memberikan penjumlahan dari jumlah NaNnilai dalam kolom, kemudian penjumlahan dari nilai-nilai tersebut:

df.isnull().sum()
0    0
1    2
2    0
3    1
4    0
5    2
dtype: int64

Akhirnya, untuk mendapatkan jumlah total nilai NaN di DataFrame:

df.isnull().sum().sum()
5

Mengapa tidak menggunakan .any(axis=None)bukan .any().any()?
Georgy

57

Untuk mengetahui baris mana yang memiliki NaN di kolom tertentu:

nan_rows = df[df['name column'].isnull()]

17
Untuk mengetahui baris tidak memiliki NaN di kolom tertentu: non_nan_rows = df[df['name column'].notnull()].
Elmex80s

49

Jika Anda perlu tahu ada berapa baris dengan "satu atau lebih NaNs":

df.isnull().T.any().T.sum()

Atau jika Anda perlu menarik baris ini dan memeriksanya:

nan_rows = df[df.isnull().T.any().T]

4
Saya pikir kita tidak perlu T
YOBEN_S


18

Menambahkan ke Hobs jawaban yang brilian, saya sangat baru untuk Python dan Panda jadi tolong tunjukkan jika saya salah.

Untuk mengetahui baris mana yang memiliki NaN:

nan_rows = df[df.isnull().any(1)]

akan melakukan operasi yang sama tanpa perlu transposing dengan menentukan sumbu dari setiap () sebagai 1 untuk memeriksa apakah 'Benar' hadir dalam baris.


Ini menghilangkan dua transpos! Cintai any(axis=1)penyederhanaan singkat Anda .
hobs

12

Sintaks Super Sederhana: df.isna().any(axis=None)

Mulai dari v0.23.2 , Anda dapat menggunakan DataFrame.isna+ di DataFrame.any(axis=None)mana axis=Nonemenentukan pengurangan logis atas seluruh DataFrame.

# 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

Alternatif yang Berguna

numpy.isnan
Opsi pemain lain jika Anda menjalankan versi panda yang lebih lama.

np.isnan(df.values)

array([[False,  True],
       [False, False],
       [ True, False]])

np.isnan(df.values).any()
# True

Atau, periksa jumlahnya:

np.isnan(df.values).sum()
# 2

np.isnan(df.values).sum() > 0
# True

Series.hasnans
Anda juga bisa menelepon berulang Series.hasnans. Misalnya, untuk memeriksa apakah satu kolom memiliki NaN,

df['A'].hasnans
# True

Dan untuk memeriksa apakah ada kolom yang memiliki NaN, Anda dapat menggunakan pemahaman dengan any(yang merupakan operasi hubungan arus pendek).

any(df[c].hasnans for c in df)
# True

Ini sebenarnya sangat cepat.


10

Karena tidak ada yang disebutkan, hanya ada variabel lain yang disebut hasnans.

df[i].hasnansakan menghasilkan Truejika satu atau lebih nilai dalam Seri panda adalah NaN, Falsejika tidak. Perhatikan bahwa ini bukan fungsi.

versi panda '0.19.2' dan '0.20.2'


6
Jawaban ini salah. Seri Pandas memiliki atribut ini tetapi DataFrames tidak. Jika df = DataFrame([1,None], columns=['foo']), maka df.hasnansakan melempar AttributeError, tetapi df.foo.hasnansakan kembali True.
Nathan Thompson

7

Karena pandasharus menemukan ini DataFrame.dropna(), saya melihat untuk melihat bagaimana mereka menerapkannya dan menemukan bahwa mereka memanfaatkan DataFrame.count(), yang menghitung semua nilai-nilai non-nol di DataFrame. Lih kode sumber panda . Saya belum membandingkan teknik ini, tetapi saya pikir penulis perpustakaan cenderung telah membuat pilihan bijak untuk melakukannya.


6

biarkan dfmenjadi nama DataFrame Pandas dan nilai apa pun yang merupakan numpy.nannilai nol.

  1. Jika Anda ingin melihat kolom mana yang memiliki nol dan yang tidak (hanya Benar dan Salah)
    df.isnull().any()
  2. Jika Anda hanya ingin melihat kolom yang memiliki nol
    df.loc[:, df.isnull().any()].columns
  3. Jika Anda ingin melihat jumlah nol di setiap kolom
    df.isna().sum()
  4. Jika Anda ingin melihat persentase nol di setiap kolom

    df.isna().sum()/(len(df))*100
  5. Jika Anda ingin melihat persentase nol dalam kolom hanya dengan nol: df.loc[:,list(df.loc[:,df.isnull().any()].columns)].isnull().sum()/(len(df))*100

EDIT 1:

Jika Anda ingin melihat di mana data Anda hilang secara visual:

import missingno
missingdata_df = df.columns[df.isnull().any()].tolist()
missingno.matrix(df[missingdata_df])

Jika Anda ingin melihat jumlah nol di setiap kolom ... Itu sepertinya gila, mengapa tidak lakukan saja df.isna().sum()?
AMC

4

Hanya menggunakan math.isnan (x) , Return True jika x adalah NaN (bukan angka), dan False sebaliknya.


4
Saya tidak berpikir math.isnan(x)akan bekerja ketika xDataFrame. Anda mendapatkan TypeError sebagai gantinya.
hlin117

Mengapa Anda menggunakan ini di atas salah satu alternatif?
AMC

4
df.isnull().sum()

Ini akan memberi Anda jumlah semua nilai NaN yang ada di masing-masing kolom DataFrame.


Tidak, itu akan memberi Anda Seri yang memetakan nama kolom ke jumlah nilai NA masing-masing.
AMC

Diperbaiki, salahku: p
Adarsh ​​singh

3

Berikut adalah cara lain yang menarik untuk menemukan null dan mengganti dengan nilai yang dihitung

    #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

3

Saya telah menggunakan berikut ini dan ketik casting ke string dan memeriksa nilai nan

   (str(df.at[index, 'column']) == 'nan')

Ini memungkinkan saya untuk memeriksa nilai spesifik dalam suatu seri dan tidak hanya kembali jika ini terdapat di suatu tempat dalam seri.


Apakah ada keuntungan menggunakan ini pandas.isna()?
AMC

2

Yang terbaik adalah menggunakan:

df.isna().any().any()

Inilah sebabnya . Jadi isna()digunakan untuk mendefinisikan isnull(), tetapi keduanya identik tentu saja.

Ini bahkan lebih cepat daripada jawaban yang diterima dan mencakup semua array panda 2D.


1

Atau Anda dapat menggunakannya .info()pada DF:

df.info(null_counts=True) yang mengembalikan jumlah baris non_null dalam kolom seperti:

<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


0
df.apply(axis=0, func=lambda x : any(pd.isnull(x)))

Akan memeriksa setiap kolom apakah itu mengandung Nan atau tidak.


Mengapa menggunakan ini di atas solusi bawaan?
AMC

0

Kita bisa melihat nilai-nilai null hadir dalam dataset dengan menghasilkan heatmap menggunakan Seaborn modul heatmap

import pandas as pd
import seaborn as sns
dataset=pd.read_csv('train.csv')
sns.heatmap(dataset.isnull(),cbar=False)

-1

Anda tidak hanya dapat memeriksa apakah ada 'NaN' tetapi juga mendapatkan persentase 'NaN di setiap kolom menggunakan yang berikut,

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

-2

Bergantung pada jenis data yang Anda hadapi, Anda juga bisa mendapatkan jumlah nilai setiap kolom saat melakukan EDA dengan menetapkan dropna ke False.

for col in df:
   print df[col].value_counts(dropna=False)

Berfungsi dengan baik untuk variabel kategori, tidak begitu banyak ketika Anda memiliki banyak nilai unik.


Saya pikir ini tidak efisien. Fungsi bawaan panda lebih rapi / terse. Hindari kekacauan notebook ipython.
Koo

Tidak ada gunanya menggunakan ini di atas solusi bawaan.
AMC
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.