【Pandas活用術】欠損値NaNを含む行・列を特定・抽出する方法


 

データ分析において、欠損値 (NaN) の存在は避けられない現実です。これらの欠損値がどこに、どれくらい存在するかを把握することは、データの前処理や分析の品質を大きく左右します。Pandasを使えば、DataFrameやSeriesの中からNaNを含む行や列を簡単に特定し、抽出することができます。この記事では、Pandasで欠損値を含むデータを見つけ出し、効率的に抽出するための主要なテクニックを、短いサンプルコードと丁寧な解説でご紹介します。


 

欠損値NaNを含む行・列を抽出する理由

 

欠損値を含む行や列を抽出する主な理由は以下の通りです。

  • 問題の特定: どのデータが欠けているのか、そのパターンを理解する手助けになります。

  • 個別対応: 欠損値のパターンによっては、個別に処理方法を検討する必要があるため、対象データを抽出して詳しく調査します。

  • 報告・可視化: 欠損値の状況を報告書にまとめたり、可視化したりする際に、抽出したデータが役立ちます。


 

PandasでNaNを含む行を抽出する

 

DataFrame全体から欠損値を含む行を抽出するには、isnull()(またはisna())とブールインデックス参照を組み合わせるのが一般的です。

 

欠損値が1つでも含まれる行を抽出する

 

最も一般的なケースで、DataFrameのどこかにNaNがある行をすべて抽出します。

Python
 
import pandas as pd
import numpy as np

# サンプルDataFrameの作成
df = pd.DataFrame({
    'A': [1, 2, np.nan, 4],
    'B': ['apple', 'banana', 'orange', np.nan],
    'C': [10, 20, 30, 40]
})
print("オリジナルDataFrame:\n", df)

# 欠損値を含む行を抽出
# df.isnull()でブール値DataFrameを作成し、.any(axis=1)でいずれかの列にTrueがあればその行はTrue
rows_with_nan = df[df.isnull().any(axis=1)]
print("\n欠損値を含む行:\n", rows_with_nan)

解説:

  1. df.isnull(): DataFrameの各要素がNaNであればTrue、そうでなければFalseのブール値DataFrameを生成します。

  2. .any(axis=1): 各行において、少なくとも1つのTrue(つまりNaN)があれば、その行全体をTrueとします。

  3. df[...]: このブール値のSeriesを使って、元のDataFrameから該当する行を抽出します。


 

全ての要素がNaNである行を抽出する

 

特定の行のすべての列がNaNである場合に、その行を抽出したいケースもあります。

Python
 
df_all_nan_row = pd.DataFrame({
    'X': [1, np.nan, 3],
    'Y': [np.nan, np.nan, 5],
    'Z': [np.nan, np.nan, 6]
})
print("\nすべての要素がNaNの行を含むDataFrame:\n", df_all_nan_row)

# すべての要素がNaNである行を抽出
# .all(axis=1)ですべての列がTrue(すべてNaN)であればその行はTrue
all_nan_rows = df_all_nan_row[df_all_nan_row.isnull().all(axis=1)]
print("\nすべての要素がNaNである行:\n", all_nan_rows)

解説:

df_all_nan_row.isnull().all(axis=1)は、各行の全ての要素がNaNである場合にTrueを返します。


 

特定の列にNaNが含まれる行を抽出する

 

特定の列(例えば'A'列)にNaNがある行だけを抽出したい場合に便利です。

Python
 
# 'A'列にNaNを含む行を抽出
rows_a_has_nan = df[df['A'].isnull()]
print("\n'A'列にNaNを含む行:\n", rows_a_has_nan)

解説:

df[‘A’].isnull()は、’A’列のSeriesに対してNaN判定を行い、直接ブール値のSeriesを返します。これをブールインデックス参照に利用します。


 

PandasでNaNを含む列を抽出する

 

行の抽出と同様に、isnull()とブールインデックス参照を組み合わせて、欠損値を含む列を抽出できます。

 

欠損値が1つでも含まれる列を抽出する

 

DataFrameのどこかにNaNがある列をすべて抽出します。

Python
 
# 欠損値を含む列を抽出
# df.isnull()でブール値DataFrameを作成し、.any(axis=0)でいずれかの行にTrueがあればその列はTrue
cols_with_nan = df.loc[:, df.isnull().any(axis=0)]
print("\n欠損値を含む列:\n", cols_with_nan)

解説:

  1. df.isnull(): ブール値DataFrameを生成します。

  2. .any(axis=0): 各列において、少なくとも1つのTrue(つまりNaN)があれば、その列全体をTrueとします。

  3. df.loc[:, ...]: このブール値のSeriesを使って、元のDataFrameから該当する列を抽出します。:はすべての行を選択することを意味します。


 

全ての要素がNaNである列を抽出する

 

特定の列のすべての要素がNaNである場合に、その列を抽出したいケースです。

Python
 
# すべての要素がNaNである列を抽出
# .all(axis=0)ですべての行がTrue(すべてNaN)であればその列はTrue
all_nan_cols = df_all_nan_row.loc[:, df_all_nan_row.isnull().all(axis=0)]
print("\nすべての要素がNaNである列:\n", all_nan_cols)

解説:

df_all_nan_row.isnull().all(axis=0)は、各列の全ての要素がNaNである場合にTrueを返します。


 

まとめ

 

Pandasで欠損値NaNを含む行や列を抽出する能力は、データクリーニングと探索的データ分析において非常に重要です。isnull() (isna()) とany()all()、そしてブールインデックス参照を組み合わせることで、データの特性に応じた柔軟な抽出が可能になります。これらのテクニックを習得し、データ分析のワークフローを効率化しましょう。