穴のあいた書き出しファイル
店の予約システムから、1年分のデータを書き出してもらいました。ところが、気温が空の日があります。99.9度の日もあります。貸出台数が「unknown」の日まであります。
このままモデルに渡すと、事実と一緒に誤りまで学んでしまいます。まずはきれいにすることです。実は、これが仕事の大半です。
このレッスンのゴール
メモ
データの中の、欠けた値と誤った値を見つけて直せる。
キーワード
| ことば | いみ | れい |
|---|---|---|
| 欠損値 | 何も入っていないセル | NaN |
| データ型 | 列に入っている値の種類 | float64 |
| 重複 | ほかの行とまったく同じ行 | |
| 外れ値 | ほかの値から大きく離れた値 | |
| 補完 | 欠けた値を、もっともらしい値で埋めること |
学生が入力するセルは、このプレビューでは空白です。
探すべき4つの傷
悪いデータの傷は、たいてい4種類です。値が欠けている。列のデータ型が違い、数が文字として入っている。行が重複している。ありえない値が入っている。
どの傷にも、pandas で短く確かめる方法があります。何かを変える前に、まず見ます。
例: 傷とその確かめ方
| 傷 | 見え方 | 確かめ方 |
|---|---|---|
| 欠損値 | セルに NaN | messy.isna().sum() |
| データ型の違い | 数のはずが object | messy.dtypes |
| 重複 | 日数より行が多い | messy.duplicated().sum() |
| ありえない値 | ありえない最大値 | messy["temp_c"].max() |
| 表記のゆれ | Sunny と sunny が別に数えられる | messy["weather"].value_counts() |
学生が入力するセルは、このプレビューでは空白です。
汚れたコピーを作って調べる
docker exec jupyter python3 steps/messy.pyここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ノートブックに入力: 欠けた行
import pandas as pd
messy = pd.read_csv("messy.csv")
# 気温が欠けている行の、日付と気温だけを見ます。
messy[messy["temp_c"].isna()][["date", "temp_c"]]
ノートブックに入力: 重複した行
# keep=False にすると、元の行も写しも両方見えます。
messy[messy.duplicated(keep=False)][["date", "hires"]]
文字の列は数の問題を隠す
数の列に言葉が1つ混じると、pandas は列全体を文字として持ちます。型は object になり、平均が出せなくなります。
pd.to_numeric(列, errors="coerce") は、読める値をすべて数に変えます。読めない値は NaN になるので、探せるようになります。
言葉にも同じわながあります。空白のついた「Sunny 」と「SUNNY」は、コンピュータには別の値です。
言葉をそろえ、台数を確かめる
# 書き出したファイルにあった、3通りの「晴れ」です。
words = ["sunny", "Sunny ", "SUNNY"]
for word in words:
print(repr(word), "→", repr(word.strip().lower()))
# 貸出台数は、数字だけでできていますか。
for text in ["318", "-3", "n/a"]:
print(text, text.isdigit())
# 2つ目のリストに "12.5" を足してください。isdigit は何と答えますか。
ノートブックに入力: おかしな台数
# 台数を数に変えます。読めない値は NaN になります。
counts = pd.to_numeric(messy["hires"], errors="coerce")
messy[counts.isna() | (counts < 0)][["date", "hires"]]
よくある間違い
注意
外れ値はすべて消すべき誤りだと考えがちです。めずらしい値でも本当のことがあります。いちばん忙しい487台の日は、実際にあった日です。消したり置きかえたりするのは、99.9度やマイナスの台数のように、ありえない値だけにします。
消す、埋める、直す、そして記録する
傷ごとに、3つのどれかを選びます。救えない行は消します。台数が「unknown」の行がそうです。正しい値がはっきりしていれば直します。「Sunny 」を「sunny」にします。推測でよければ補完します。気温の中央値で埋めます。
元のファイルは変えずに残し、コピーをきれいにします。そうすれば、どの手順も確かめ直せて、もう一度実行できます。
例: きれいにする手順の順番
| 手順 | 残った行 | 理由 |
|---|---|---|
| messy.csv を読む | 367 | 書き出したままの状態 |
| drop_duplicates | 365 | 2行が重複していた |
| 台数が0以上の行だけ残す | 363 | 「unknown」と -5 は台数でない |
| 45度を超える気温を欠損にする | 363 | 99.9 も欠損の仲間になる |
| 欠けた気温を中央値で埋める | 363 | ここでは空よりも推測がよい |
学生が入力するセルは、このプレビューでは空白です。
きれいにする手順を実行する
docker exec jupyter python3 steps/clean.pyここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
さらに挑戦: 月ごとの中央値で埋める
ノートブックで、messy.csv を別のやり方できれいにしてください。1年全体の中央値ではなく、その日の月の中央値で、欠けた気温を埋めます。
ヒント: groupby("month")["temp_c"].transform("median") で、各行にその月の中央値が入ります。1月21日と6月1日の値を、1年全体の中央値と比べましょう。どちらがもっともらしいか、理由も書きます。