【Pandas活用術】欠損値NaNを含む行・列を特定・抽出する方法
データ分析において、欠損値 (NaN) の存在は避けられない現実です。これらの欠損値がどこに、どれくらい存在するかを把握することは、データの前処理や分析の品質を大きく左右します。Pandasを使えば、DataFrameやSeriesの中からNaNを含む行や列を簡単に特定し、抽出することができます。この記事では、Pandasで欠損値を含むデータを見つけ出し、効率的に抽出するための主要なテクニックを、短いサンプルコードと丁寧な解説でご紹介します。
欠損値NaNを含む行・列を抽出する理由
欠損値を含む行や列を抽出する主な理由は以下の通りです。
-
問題の特定: どのデータが欠けているのか、そのパターンを理解する手助けになります。
-
個別対応: 欠損値のパターンによっては、個別に処理方法を検討する必要があるため、対象データを抽出して詳しく調査します。
-
報告・可視化: 欠損値の状況を報告書にまとめたり、可視化したりする際に、抽出したデータが役立ちます。
PandasでNaNを含む行を抽出する
DataFrame全体から欠損値を含む行を抽出するには、isnull()(またはisna())とブールインデックス参照を組み合わせるのが一般的です。
欠損値が1つでも含まれる行を抽出する
最も一般的なケースで、DataFrameのどこかにNaNがある行をすべて抽出します。
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)
解説:
-
df.isnull(): DataFrameの各要素がNaNであればTrue、そうでなければFalseのブール値DataFrameを生成します。 -
.any(axis=1): 各行において、少なくとも1つのTrue(つまりNaN)があれば、その行全体をTrueとします。 -
df[...]: このブール値のSeriesを使って、元のDataFrameから該当する行を抽出します。
全ての要素がNaNである行を抽出する
特定の行のすべての列がNaNである場合に、その行を抽出したいケースもあります。
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がある行だけを抽出したい場合に便利です。
# '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がある列をすべて抽出します。
# 欠損値を含む列を抽出
# df.isnull()でブール値DataFrameを作成し、.any(axis=0)でいずれかの行にTrueがあればその列はTrue
cols_with_nan = df.loc[:, df.isnull().any(axis=0)]
print("\n欠損値を含む列:\n", cols_with_nan)
解説:
-
df.isnull(): ブール値DataFrameを生成します。 -
.any(axis=0): 各列において、少なくとも1つのTrue(つまりNaN)があれば、その列全体をTrueとします。 -
df.loc[:, ...]: このブール値のSeriesを使って、元のDataFrameから該当する列を抽出します。:はすべての行を選択することを意味します。
全ての要素がNaNである列を抽出する
特定の列のすべての要素がNaNである場合に、その列を抽出したいケースです。
# すべての要素が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()、そしてブールインデックス参照を組み合わせることで、データの特性に応じた柔軟な抽出が可能になります。これらのテクニックを習得し、データ分析のワークフローを効率化しましょう。

