実際のデータ分析現場では、すべてのデータが綺麗に揃っていることは稀であり、測定ミスやシステムエラーによって発生した「欠損値(NaN / None)」への対処が必須となります。Pandasには、これらの欠損値を効率的に検出し、適切に処理(除去や補完)するための機能が備わっています。
本記事では、isnull() による欠損値の有無の確認と、dropna() による欠損値データの削除方法について解説します。
目次
欠損値処理の基本メソッド
isnull()/isna(): 要素が欠損値であればTrue、そうでなければFalseを返します。any(): 列や行の中に一つでもTrueがあればTrueを返します。isnull()と組み合わせて使用します。dropna(): 欠損値が含まれる行(または列)を削除します。
実装サンプルコード
ここでは、工場の生産ラインにおける「センサーログデータ」を題材にします。通信エラー等により、一部の時刻で温度や振動データが記録されていない(欠損している)状況を想定します。
import pandas as pd
import numpy as np
def handle_missing_values():
"""
DataFrame内の欠損値(NaN)の判定と除去を実演する関数
"""
# 1. サンプルデータの作成
# np.nan や None を含めることで意図的に欠損値を作ります
sensor_data = {
"Time": ["09:00", "09:10", "09:20", "09:30", "09:40"],
"Temperature": [120.5, np.nan, 119.8, 121.2, np.nan], # 2箇所欠損
"Vibration": [0.05, 0.06, 0.04, None, 0.05] # 1箇所欠損
}
df = pd.DataFrame(sensor_data)
print("--- 元のセンサーデータ(欠損あり) ---")
print(df)
print("\n")
# 2. 欠損値の判定 (isnull + any)
print("=== 欠損値の判定 ===")
# DataFrame全体に対して確認
# 列ごとに「欠損値が含まれているか?」をTrue/Falseで返します
has_null = df.isnull().any()
print("--- 各列の欠損有無 ---")
print(has_null)
# 特定の列だけを確認する場合
is_temp_null = pd.isnull(df["Temperature"]).any()
print(f"\nTemperature列に欠損はあるか: {is_temp_null}")
# 3. 欠損値の除去 (Seriesでの操作)
print("\n=== 欠損値の除去 (Series) ===")
# Temperature列を取り出し、欠損しているデータを削除
temp_series = df["Temperature"]
clean_temp_series = temp_series.dropna()
print("--- 除去後のTemperature列 ---")
print(clean_temp_series)
print(f"元の要素数: {len(temp_series)} -> 除去後: {len(clean_temp_series)}")
# 4. 欠損値の除去 (DataFrameでの操作)
print("\n=== 欠損値の除去 (DataFrame) ===")
# 欠損値が「1つでも」含まれる行をすべて削除します
# (デフォルトの挙動: how='any', axis=0)
df_clean = df.dropna()
print("--- 欠損を含む行を削除したDataFrame ---")
print(df_clean)
# 補足: インデックスが飛び飛びになるため、必要に応じてリセットします
# df_clean = df_clean.reset_index(drop=True)
if __name__ == "__main__":
handle_missing_values()
実行結果
--- 元のセンサーデータ(欠損あり) ---
Time Temperature Vibration
0 09:00 120.5 0.05
1 09:10 NaN 0.06
2 09:20 119.8 0.04
3 09:30 121.2 NaN
4 09:40 NaN 0.05
=== 欠損値の判定 ===
--- 各列の欠損有無 ---
Time False
Temperature True
Vibration True
dtype: bool
Temperature列に欠損はあるか: True
=== 欠損値の除去 (Series) ===
--- 除去後のTemperature列 ---
0 120.5
2 119.8
3 121.2
Name: Temperature, dtype: float64
元の要素数: 5 -> 除去後: 3
=== 欠損値の除去 (DataFrame) ===
--- 欠損を含む行を削除したDataFrame ---
Time Temperature Vibration
0 09:00 120.5 0.05
2 09:20 119.8 0.04
解説
isnull():isna()と全く同じ機能を持つメソッドです。どちらを使っても構いませんが、プロジェクト内で統一することが望ましいです。dropna()の挙動: DataFrameに対して実行すると、デフォルトでは「いずれかの列にNaNがある行」を削除します。how='all': 全ての列がNaNの場合のみ削除したいときに指定します。subset=['Temperature']: 特定の列に欠損がある場合のみ削除したいときに指定します。
データクリーニングの第一歩として、まずはデータの欠損状況を把握し、分析の目的に合わせて「削除する」か「特定の値(平均値など)で埋める」かを判断する必要があります。
