Python環境を起動中... 初回のみ数秒かかります
Lesson 7 / 12

欠損値の扱い

このレッスンで学ぶこと

  • 欠損値(NaN)とは何かを理解できる
  • isna で欠損の有無・件数を確認できる
  • fillna で欠損を補完できる(固定値・平均値)
  • dropna で欠損のある行を削除できる

1. 欠損値(NaN)とは

現実のデータには、値が入っていない箇所がよくあります。 「検査を受けていない」「記録が漏れた」「測定不能だった」——こうしたデータの抜け欠損値と呼び、pandasでは NaN(Not a Number)として表されます。

欠損値をそのままにしておくと、集計や分析が正しくできなかったり、エラーの原因になったりします。 そこで、データ分析では「欠損値をどう扱うか」を最初に決めるのが定石です。 選択肢は大きく2つ——「埋める(補完)」「捨てる(削除)」です。

🤖 AI用語メモ — 「欠損値処理」は前処理の必須工程:
機械学習では、欠損値があるとモデルがうまく学習できないことが多く、 「欠損値をどう埋めるか/捨てるか」はAI学習の前処理で必ず通る工程です。 このレッスンで学ぶ fillnadropna は、そのままAIのためのデータ準備に使えます。

2. 欠損を見つける(isna)

まずは「どこに、いくつ欠損があるか」を把握します。df.isna() は、 各セルが欠損か(True / False)を判定します。これに .sum() を付けると、 列ごとの欠損件数が一目で分かります。

sample_1.py
Ctrl+Enter
出力

💡 欠損があると数値が小数になる: 上の SBP 列は整数のつもりでも、欠損(NaN)が混じると 120.0 のように 小数(float)で表示されます。これはNaNが小数として扱われる仕様によるものです。 欠損を埋めたり除いたりした後は、必要に応じて型を整数に戻せます(型変換はレッスン8で扱います)。

3. 欠損を埋める(fillna)

欠損値を何らかの値で埋めるのが fillna(値) です。 埋める値の選び方には、主に次のパターンがあります。

sample_2.py
Ctrl+Enter
出力

💡 平均は「欠損を無視して」計算される: df["SBP"].mean() は、欠損(NaN)を除いた値だけで平均を計算します。 上の例では (120+145+138)/3 = 134.33 です。その平均で欠損を埋めることで、 データ全体の傾向を大きく崩さずに穴を埋められます。これが数値データの欠損補完の定番手法です。

💡 .round(n) で小数を丸める: 上のコードの .round(2) は、数値を小数第2位までに丸めるメソッドです(round(値, 2) でも同じ)。 134.333… のような長い小数を 134.33 と見やすく整えるために使います。 列(Series)にもDataFrame全体にも使えて、表示を整えたいときに便利です。

4. 欠損を削除する(dropna)

補完するのではなく、欠損のある行をまるごと削除するのが dropna() です。 「欠損が少なく、その行を捨てても分析に影響しない」場合に使います。

sample_3.py
Ctrl+Enter
出力

⚠ dropna は「捨てすぎ」に注意: dropna() は、1つでも欠損がある行をすべて削除します。 欠損が多いデータで安易に使うと、大量の行が消えてしまうことがあります。 上の例でも5行中3行が削除され、残ったのは2行だけです。 「削除」と「補完」のどちらが適切かは、欠損の量と分析の目的で判断しましょう。

💡 補完 vs 削除の使い分け:

  • 欠損が少ないdropna() で削除しても影響は小さい
  • 欠損が多い・データを残したいfillna() で補完
  • 「未測定」自体が意味を持つ → "不明" などで埋めて区別する

5. 練習問題

問題 1

列ごとの欠損数を数えよう

下記の df について、列ごとの欠損件数isna().sum() で表示してください。

exercise_1.py
出力
ヒントを見る(答え+解説)
import pandas as pd

df = pd.DataFrame({
    "患者ID": ["P001","P002","P003","P004"],
    "SBP":   [120, None, 145, None],
    "体温":   [36.5, 37.2, None, 38.1],
})

# 列ごとの欠損件数を表示してください
print(df.isna().sum())   # 患者ID=0, SBP=2, 体温=1

df.isna() で各セルが欠損かを判定し、.sum() で列ごとに合計すると、欠損件数が一覧できます。SBPは2件、体温は1件の欠損があります。

問題 2

欠損を平均値で埋めよう

下記の dfSBP 列の欠損を、その列の平均値で埋めてください。

exercise_2.py
出力
ヒントを見る(答え+解説)
import pandas as pd

df = pd.DataFrame({
    "患者ID": ["P001","P002","P003","P004"],
    "SBP":   [120, 140, None, 160],
})

# SBP列の欠損を、SBPの平均値で埋めて表示してください
filled = df["SBP"].fillna(df["SBP"].mean())
print(list(filled))   # [120.0, 140.0, 140.0, 160.0]

欠損を除いた平均は (120+140+160)/3 = 140.0fillna(df["SBP"].mean()) で、欠損していたP003が平均値140.0で埋まります。数値データの欠損補完の最も基本的なやり方です。

問題 3

欠損のある行を削除しよう

下記の df から、dropna()欠損のある行を削除し、残った行数を表示してください。

exercise_3.py
出力
ヒントを見る(答え+解説)
import pandas as pd

df = pd.DataFrame({
    "患者ID": ["P001","P002","P003","P004","P005"],
    "SBP":   [120, None, 145, 138, 160],
    "BMI":   [22.5, 28.1, None, 26.2, 30.5],
})

# 欠損のある行を削除し、残った行数も表示してください
clean = df.dropna()
print(clean)
print("残り:", len(clean), "行")   # 3行(P001, P004, P005)

dropna() は1つでも欠損がある行を削除します。P002(SBP欠損)とP003(BMI欠損)が消え、残るのは P001・P004・P005 の3行です。

6. まとめ

このレッスンのポイント

  • 欠損値はpandasでは NaN として表される(None を書くとNaNになる)
  • df.isna().sum() で列ごとの欠損件数を確認
  • fillna(値) で補完(固定値・平均値など)
  • 平均(mean)は欠損を無視して計算される
  • dropna() で欠損のある行を削除(捨てすぎに注意)
  • 補完か削除かは、欠損の量と目的で判断する

自由に試してみましょう:

free_practice.py
出力

完了するとコース一覧に進捗が記録されます