Pandas DataFrameで値がNaNかどうかを確認する方法


483

Python Pandasで、DataFrameに1つ(または複数)のNaN値があるかどうかを確認する最良の方法は何ですか?

私は関数について知っていますpd.isnanが、これは各要素に対してブール値のDataFrameを返します。この投稿はここでも私の質問に正確に答えるものではありません。


回答:


577

jwilnerの応答はその場にあります。私の経験では、フラットな配列を合計することは(奇妙なことに)カウントするよりも速いので、より速いオプションがあるかどうかを調べようとしていました。このコードはより高速に見えます:

df.isnull().values.any()

例えば:

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()少し遅いですが、もちろん、追加情報-の数がありNaNsます。


1
時間のベンチマークをありがとうございます。pandasこのための組み込み関数がないのは驚くべきことです。これdf.describe()を実行できることは@JGreenwellの投稿に当てはまりますが、直接的な機能はありません。
hlin117 2015

2
私はdf.describe()NaNs を見つけることなく)ちょうど時間を計った。1000 x 1000アレイでは、1回の呼び出しに1.15秒かかります。
hlin117 2015

3
:1、また、df.isnull().values.sum()より少し速いdf.isnull().values.flatten().sum()
ゼロ

ああ、良いキャッチ@JohnGalt-私は自分の解決策を変更して.flatten()、ポスター用のを削除します。ありがとう。
アナンド2015

6
あなたは試しませんでしたdf.isnull().values.any()、私にとっては他の人よりも速いです。
CK1 2015

178

いくつかのオプションがあります。

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

データフレームは次のようになります。

          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
  • オプション1df.isnull().any().any()-これはブール値を返します

isnull()次のようなデータフレームを返すものを知っています。

       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

作成するとdf.isnull().any()NaN値を持つ列だけが見つかります。

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

.any()上記のいずれかがある場合はもう1つ通知されますTrue

> df.isnull().any().any()
True
  • オプション2df.isnull().sum().sum()-これは、値の総数の整数を返しNaNます。

これはと同じように動作.any().any()し、最初にNaN列の値の数の合計を与え、次にそれらの値の合計を与えます。

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

最後に、DataFrameのNaN値の総数を取得します。

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

.any(axis=None)代わりに使用しないのはなぜ.any().any()ですか?
ジョージー


49

NaNs」が1つ以上ある行がいくつあるかを知る必要がある場合:

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

または、これらの行を引き出して調べる必要がある場合:

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

4
私たちは第二Tを必要としないと思う
YOBEN_S

38

df.isnull().any().any() それを行う必要があります。


18

ホブの素晴らしい答えに加えて、私はPythonとPandasに非常に慣れていないので、私が間違っているかどうか指摘してください。

どの行にNaNがあるかを調べるには:

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

「True」が行に存在するかどうかを確認するためにany()の軸を1として指定することにより、転置する必要なしに同じ操作を実行します。


これは2つの転置を取り除きます!あなたの簡潔なany(axis=1)簡素化が大好きです。
2018

12

超シンプルな構文: df.isna().any(axis=None)

v0.23.2以降DataFrame.isna+ を使用できます。DataFrame.any(axis=None)ここでaxis=None、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

便利な代替手段

numpy.isnan
古いバージョンのパンダを実行している場合の別のパフォーマンスオプション。

np.isnan(df.values)

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

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

または、合計を確認します。

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

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

Series.hasnans
を繰り返し呼び出すこともできますSeries.hasnans。たとえば、単一の列にNaNがあるかどうかを確認するには、

df['A'].hasnans
# True

そして、いずれかの列にNaN があるかどうを確認するanyには、(短絡演算)で内包表記を使用できます。

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

これは実際非常に高速です。


10

誰も言及していないので、と呼ばれる別の変数がありますhasnans

df[i].hasnansTrueパンダシリーズの1つ以上の値がNaNであるFalse場合に出力されます(そうでない場合)。関数ではないことに注意してください。

パンダのバージョン「0.19.2」と「0.20.2」


6
この答えは間違っています。パンダシリーズにはこの属性がありますが、データフレームにはありません。の場合df = DataFrame([1,None], columns=['foo'])df.hasnansをスローしますがAttributeErrordf.foo.hasnans戻りTrueます。
Nathan Thompson

7

についてこれpandasを見つける必要があるのでDataFrame.dropna()、私は彼らがそれをどのように実装するかを調べてみたところ、を使用していることがわかりDataFrame.count()ましたDataFrame。Cf. パンダのソースコード。私はこの手法をベンチマークしていませんが、ライブラリの作成者がそれを行う方法について賢明な選択をした可能性が高いと思います。


6

聞かせてdfパンダデータフレームの名前と任意の値であることがnumpy.nanヌル値です。

  1. どの列にnullがあり、どの列にnullがないかを確認する場合(TrueとFalseのみ)
    df.isnull().any()
  2. nullのある列のみを表示する場合
    df.loc[:, df.isnull().any()].columns
  3. すべての列のnullの数を確認する場合
    df.isna().sum()
  4. すべての列のnullの割合を表示する場合

    df.isna().sum()/(len(df))*100
  5. nullのみを含む列のnullの割合を表示する場合: df.loc[:,list(df.loc[:,df.isnull().any()].columns)].isnull().sum()/(len(df))*100

編集1:

データが不足している場所を視覚的に確認したい場合:

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

すべての列のnullの数を確認したい場合...それは正気ではないように思われますが、なぜそうしないのdf.isna().sum()ですか?
AMC

4

math.isnan(x)を使用するだけで 、xがNaN(数値ではない)の場合はTrueを返し、それ以外の場合はFalseを返します。


4
がDataFrameのmath.isnan(x)場合xは機能しないと思います。代わりにTypeErrorを受け取ります。
hlin117

なぜこれを代替手段のどれよりも使用するのですか?
AMC

4
df.isnull().sum()

これにより、DataFrameのそれぞれの列に存在するすべてのNaN値の数がわかります。


いいえ、それは列名をそれぞれのNA値の数にマップするシリーズを提供します。
AMC

修正済み、私の責任:p
Adarsh sing

3

nullを見つけて計算値で置き換える別の興味深い方法を次に示します

    #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

私は以下を使用して文字列に型キャストし、nan値をチェックしています

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

これにより、シリーズ内の特定の値を確認できます。これがシリーズ内のどこかに含まれている場合に返すだけではありません。


これを使用する利点はありますpandas.isna()か?
AMC

2

最高のものを使用するでしょう:

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

これが理由です。したがって、isna()はを定義するためisnull()に使用されますが、これらはもちろん同じです。

これは受け入れられた回答よりもさらに速く、すべての2Dパンダ配列をカバーしています。


1

または.info()、次のDFように使用できます。

df.info(null_counts=True) 次のような列のnull以外の行の数を返します。

<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)))

Nanが含まれているかどうか、各列をチェックします。


なぜこれを組み込みのソリューションのどれよりも使用するのですか?
AMC

0

Seabornモジュールのヒートマップを使用してヒートマップを生成することにより、データセットに存在するnull値を確認できます

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

-1

次のようにして、「NaN」が存在するかどうかを確認するだけでなく、各列の「NaN」の割合も取得できます。

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

処理するデータのタイプによっては、dropnaをFalseに設定することで、EDAの実行中に各列の値のカウントを取得することもできます。

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

カテゴリ変数に対して有効に機能しますが、一意の値が多数ある場合はそれほど効果的ではありません。


これは非効率だと思います。パンダの組み込み関数は、より簡潔です。ipythonノートブックが乱雑にならないようにします。
Koo

組み込みのソリューションでこれを使用しても意味がありません。
AMC
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.