pandasで欠損値NaNが含まれているか判定、個数をカウント
pandas.DataFrame, Seriesに欠損値NaNが含まれているか判定する方法、および、欠損値NaNの個数をカウントする方法について説明する。isnull(), isna(), notnull(), notna()メソッドなどを使う。
欠損値NaNを削除・置換する方法、欠損値NaNに限らず特定の条件を満たす要素の数をカウントする方法については以下の記事を参照。
- 関連記事: pandasで欠損値NaNを削除(除外)するdropna
- 関連記事: pandasで欠損値NaNを置換(穴埋め)するfillna
- 関連記事: pandasで特定の条件を満たす要素数をカウント(全体、行・列ごと)
なお、pandasではNaN(Not a Number: 非数)のほか、Noneも欠損値として扱われる。
本記事のサンプルコードのpandasのバージョンは以下の通り。バージョンによって仕様が異なる可能性があるので注意。例として、空白を含むCSVファイルを読み込んで先頭3行を使う。
import pandas as pd
print(pd.__version__)
# 2.0.3
df = pd.read_csv('data/src/sample_pandas_normal_nan.csv')[:3]
print(df)
# name age state point other
# 0 Alice 24.0 NY NaN NaN
# 1 NaN NaN NaN NaN NaN
# 2 Charlie NaN CA NaN NaN
isnull(), isna()で要素ごとに欠損値か判定
pandas.DataFrame, Seriesにはisnull(), isna()メソッドがある。pandas.Seriesの例は最後にまとめて紹介する。
- pandas.DataFrame.isnull — pandas 2.0.3 documentation
- pandas.DataFrame.isna — pandas 2.0.3 documentation
各要素に対して判定を行い、欠損値NaNであればTrue、欠損値でなければFalseとなる。
print(df.isnull())
# name age state point other
# 0 False False False True True
# 1 True True True True True
# 2 False True False True True
print(df.isna())
# name age state point other
# 0 False False False True True
# 1 True True True True True
# 2 False True False True True
isnull()はisna()のエイリアスで使い方はどちらも同じ。以降は主にisnull()を用いるが、isna()に置き換えてもよい。
反対に欠損値NaNでなければTrue、欠損値であればFalseとするメソッドnotnull(), notna()もある。notnull()はnotna()のエイリアスで使い方はどちらも同じ。
- pandas.DataFrame.notnull — pandas 2.0.3 documentation
- pandas.DataFrame.notna — pandas 2.0.3 documentation
print(df.notnull())
# name age state point other
# 0 True True True False False
# 1 False False False False False
# 2 True False True False False
print(df.notna())
# name age state point other
# 0 True True True False False
# 1 False False False False False
# 2 True False True False False
なお、欠損値NaNはあらゆる値(NaN自身を含む)に対して、==はFalse、!=はTrueを返す。==や!=では欠損値であるかの判定はできないので注意。
- 関連記事: Pythonにおけるnanの判定
print(df == float('nan'))
# name age state point other
# 0 False False False False False
# 1 False False False False False
# 2 False False False False False
print(df != float('nan'))
# name age state point other
# 0 True True True True True
# 1 True True True True True
# 2 True True True True True
行・列ごとにすべての要素が欠損値か判定
all()は行・列ごとにすべての要素がTrueであればTrueと判定するメソッド。pandas.DataFrameから呼ぶとpandas.Seriesを返す。
all()をisnull()の結果に適用することで、行・列ごとにすべての要素が欠損値NaNか判定できる。
デフォルトでは列、引数axis=1とすると行に対して処理される。
print(df.isnull().all())
# name False
# age False
# state False
# point True
# other True
# dtype: bool
print(df.isnull().all(axis=1))
# 0 False
# 1 True
# 2 False
# dtype: bool
行・列ごとに欠損値をひとつでも含むか判定
any()は行・列ごとにTrueがひとつでもあればTrueと判定するメソッド。pandas.DataFrameから呼ぶとpandas.Seriesを返す。
any()をisnull()の結果に適用することで、行・列ごとに欠損値NaNをひとつでも含むか判定できる。
デフォルトでは列、引数axis=1とすると行に対して処理される。
print(df.isnull().any())
# name True
# age True
# state True
# point True
# other True
# dtype: bool
print(df.isnull().any(axis=1))
# 0 True
# 1 True
# 2 True
# dtype: bool
行・列ごとに欠損値の個数をカウント
sum()は行・列ごとに合計を算出するメソッド。pandas.DataFrameから呼ぶとpandas.Seriesを返す。
sum()ではTrue=1, False=0として処理されるため、sum()をisnull()の結果に適用することで、行・列ごとに欠損値NaNの個数をカウントできる。
デフォルトでは列、引数axis=1とすると行に対して処理される。
print(df.isnull().sum())
# name 1
# age 2
# state 1
# point 3
# other 3
# dtype: int64
print(df.isnull().sum(axis=1))
# 0 2
# 1 5
# 2 3
# dtype: int64
行・列ごとに欠損値でない要素の個数をカウント
count()は行・列ごとに欠損値NaNでない要素の個数をカウントするメソッド。pandas.DataFrameから呼ぶとpandas.Seriesを返す。
isnull()の結果ではなく、元のpandas.DataFrameから直接呼べばよい。
デフォルトでは列、引数axis=1とすると行に対して処理される。
print(df.count())
# name 2
# age 1
# state 2
# point 0
# other 0
# dtype: int64
print(df.count(axis=1))
# 0 3
# 1 0
# 2 2
# dtype: int64
欠損値の総数をカウント
pandas.DataFrameのvalues属性で要素全体のデータをNumPy配列numpy.ndarrayとして取得できる。
print(df.isnull().values)
# [[False False False True True]
# [ True True True True True]
# [False True False True True]]
print(type(df.isnull().values))
# <class 'numpy.ndarray'>
pandas.DataFrameのメソッドsum()と異なり、numpy.ndarrayのメソッドsum()はデフォルトで全体の合計を算出する。
したがって、isnull()の結果のvalues属性(numpy.ndarray)からsum()を呼ぶと全体の欠損値の個数(総数)が取得できる。
print(df.isnull().values.sum())
# 10
欠損値でない要素の総数をカウント
欠損値でない要素の総数はcount()で取得できる行または列ごとの個数の合計をsum()で算出すればよい。
print(df.count().sum())
# 5
notnull()またはnotna()(欠損値でない要素がTrue)の結果のvalues属性(numpy.ndarray)からsum()を呼んでもよい。
print(df.notnull().values.sum())
# 5
全体にひとつでも欠損値が含まれているかを判定
上で示した欠損値の総数を使って、全体に欠損値が含まれているかを判定できる。
欠損値の総数が0でなければ、全体に少なくとも一つは欠損値NaNが含まれている。
print(df.isnull().values.sum() != 0)
# True
欠損値の総数がsize属性(全要素数)と等しければ、全要素が欠損値NaNである。
print(df.size)
# 15
print(df.isnull().values.sum() == df.size)
# False
pandas.Seriesの場合
pandas.Seriesにもisnull(), isna(), notnull(), notna()といったメソッドがある。これまでの例と同様に処理できる。
- pandas.Series.isnull — pandas 2.0.3 documentation
- pandas.Series.isna — pandas 2.0.3 documentation
- pandas.Series.notnull — pandas 2.0.3 documentation
- pandas.Series.notna — pandas 2.0.3 documentation
s = df['state']
print(s)
# 0 NY
# 1 NaN
# 2 CA
# Name: state, dtype: object
print(s.isnull())
# 0 False
# 1 True
# 2 False
# Name: state, dtype: bool
print(s.notnull())
# 0 True
# 1 False
# 2 True
# Name: state, dtype: bool
print(s.isnull().any())
# True
print(s.isnull().all())
# False
print(s.isnull().sum())
# 1
print(s.count())
# 2