Pythonデータ分析レシピ集

Python Pandasで欠損値を効率的に処理する方法:検出・削除・補完のレシピ

Tags: Python, Pandas, データ前処理, 欠損値, データクレンジング

はじめに:データ分析における欠損値の重要性

データ分析を行う際、私たちが扱うデータにはしばしば「欠損値」が含まれています。これは、データが記録されなかったり、取得できなかったり、あるいは何らかの理由で無効な値として表現されたりするものです。Pythonのデータ分析ライブラリPandasでは、このような欠損値は通常 NaN (Not a Number) として表現されます。

欠損値がデータセットに存在すると、統計量の計算が不正確になったり、機械学習モデルの訓練に悪影響を与えたり、あるいは単純に処理がエラーで停止してしまったりする原因となります。そのため、データ分析の初期段階で欠損値を適切に処理することは、分析結果の信頼性を高め、スムーズな作業を進める上で非常に重要です。

この記事では、Pandasを使ってデータセット内の欠損値を「検出」し、不要な欠損値を「削除」し、そして分析に必要な欠損値を適切な値で「補完」する方法について、具体的なコードレシピとともに詳しく解説します。

問題提起:データ内の欠損値にどう対応するか

データ分析の現場では、以下のような課題に直面することがよくあります。

これらの課題を解決するために、これからご紹介するPandasの機能を活用し、効率的かつ適切に欠損値を処理する手順を習得しましょう。

解決策(コードレシピ):欠損値の検出・削除・補完

まず、サンプルデータを作成し、欠損値の処理方法を実践的に見ていきます。

1. 必要なライブラリのインポートとサンプルデータの準備

import pandas as pd
import numpy as np

# サンプルDataFrameの作成
data = {
    'A': [1, 2, np.nan, 4, 5],
    'B': [np.nan, 20, 30, np.nan, 50],
    'C': [100, 200, 300, 400, 500],
    'D': [1, 2, 3, 4, np.nan]
}
df = pd.DataFrame(data)

print("元のDataFrame:")
print(df)
print("-" * 30)

このコードでは、Pandasと数値計算ライブラリNumPyをインポートし、意図的に np.nan (NumPyの欠損値表現) を含むDataFrame df を作成しています。

2. 欠損値の検出

DataFrameに欠損値が含まれているかどうか、またどこに、どれくらい含まれているかを把握します。

# DataFrame全体の欠損値の有無を確認
print("DataFrame全体の欠損値の有無:")
print(df.isnull().any().any())
print("-" * 30)

# 各列の欠損値の数をカウント
print("各列の欠損値の数:")
print(df.isnull().sum())
print("-" * 30)

# 欠損値がある行を全て表示
print("欠損値を含む行:")
print(df[df.isnull().any(axis=1)])
print("-" * 30)

3. 欠損値の削除

欠損値を含む行や列を削除する方法です。

# 欠損値を含む行を削除(デフォルト)
df_dropped_rows = df.dropna()
print("欠損値を含む行を削除したDataFrame:")
print(df_dropped_rows)
print("-" * 30)

# 全ての要素が欠損値である行を削除
df_drop_all_nan_rows = df.dropna(how='all')
print("全ての要素が欠損値である行を削除したDataFrame:")
print(df_drop_all_nan_rows) # このサンプルデータでは該当する行がないため、元の行数は維持されます
print("-" * 30)

# 欠損値を含む列を削除
df_dropped_cols = df.dropna(axis=1)
print("欠損値を含む列を削除したDataFrame:")
print(df_dropped_cols)
print("-" * 30)

# 'B'列に欠損値がある行のみを削除
df_drop_col_B = df.dropna(subset=['B'])
print("'B'列に欠損値がある行のみを削除したDataFrame:")
print(df_drop_col_B)
print("-" * 30)

# 変更を元のDataFrameに適用する (inplace=True)
# df.dropna(inplace=True)
# print("元のDataFrameが変更された後の状態:")
# print(df)
# print("-" * 30)

4. 欠損値の補完

欠損値を特定の値や統計量、あるいは前後の値で埋める方法です。

# 欠損値を0で補完
df_fill_zero = df.fillna(0)
print("欠損値を0で補完したDataFrame:")
print(df_fill_zero)
print("-" * 30)

# 各列の平均値で欠損値を補完
df_fill_mean = df.fillna(df.mean())
print("各列の平均値で欠損値を補完したDataFrame:")
print(df_fill_mean)
print("-" * 30)

# 'B'列のみ中央値で補完
df_fill_b_median = df.copy() # オリジナルを保つためコピー
b_median = df_fill_b_median['B'].median()
df_fill_b_median['B'].fillna(b_median, inplace=True)
print("'B'列のみ中央値で補完したDataFrame:")
print(df_fill_b_median)
print("-" * 30)

# 直前の値で欠損値を補完 (forward fill)
df_ffill = df.fillna(method='ffill')
print("直前の値で欠損値を補完したDataFrame (ffill):")
print(df_ffill)
print("-" * 30)

# 直後の値で欠損値を補完 (backward fill)
df_bfill = df.fillna(method='bfill')
print("直後の値で欠損値を補完したDataFrame (bfill):")
print(df_bfill)
print("-" * 30)

# 変更を元のDataFrameに適用する (inplace=True)
# df.fillna(0, inplace=True)
# print("元のDataFrameが変更された後の状態:")
# print(df)
# print("-" * 30)

コードの詳細解説

ここでは、上記のコードレシピで使用したPandasの関数やメソッドについて、その機能と使い方を詳しく解説します。

1. 欠損値の検出:isnull() / isna()sum()

2. 欠損値の削除:dropna()

dropna() メソッドは、欠損値を含む行や列を削除するために使用します。

3. 欠損値の補完:fillna()

fillna() メソッドは、欠損値を指定した値や、あるルールに基づいて計算された値で埋めるために使用します。

まとめ:欠損値処理でデータ分析をスムーズに

この記事では、PythonのPandasライブラリを用いて、データ分析における欠損値の基本的な処理方法を網羅的に解説しました。

これらの手法を適切に使いこなすことで、データクレンジングの時間を短縮し、より正確で信頼性の高い分析結果を得ることができます。データ分析の最初のステップとして欠損値処理をマスターすることは、その後のモデリングや可視化といった作業を円滑に進めるための重要な土台となります。ぜひ、ご自身のデータに適用して、その効果を実感してください。