Day 043 — データの読み込みと基本確認

2026-05-23 白 / Phase 1 コーディング データ確認

📚 背景知識(読んでから問題へ)

Kaggleコンペでデータが与えられたとき、いきなりモデルを作るのは厳禁です。まず「データの全体像を把握する」ことから始めます。これをEDA(探索的データ分析)の第一歩と呼びます。

df.shape

行数・列数を確認
例: (891, 12) → 891行12列

df.dtypes

各列のデータ型を確認
int64 / float64 / object

df.describe()

数値列の統計量まとめ
mean / std / min / max …

df.info()

型・欠損数・メモリを一覧
Non-Null Count に注目

データ型(dtypes)の種類

dtypes意味代表例
int64整数年齢(欠損なし)、チケットクラス
float64小数 or 欠損を含む整数運賃、欠損ありの年齢
object文字列(カテゴリ変数も含む)名前、性別
💡
整数列に欠損があると float64 になる: pandasは整数に欠損(NaN)を格納できないため、欠損を含む整数列は自動的に float64 になります。Age列が float64 なのはこのためです。

🗂️ データスキーマ

今回使用する架空のタイタニック号データ(10行9列)のスキーマです。

列名列番号説明欠損
PassengerIdint640乗客IDなし
Survivedint641生存フラグ (0/1)なし
Pclassint642チケットクラス (1/2/3)なし
Nameobject3乗客名なし
Sexobject4性別 (male/female)なし
Agefloat645年齢2件あり(行5・6)
SibSpint646兄弟・配偶者数なし
Parchint647親・子供数なし
Farefloat648運賃なし

📊 describe() の読み方

Age列の describe() 出力例です。各行の意味を確認してください。

統計量Age の値意味
count8.0 欠損を除いた有効行数 → 10行中8行有効 = 2件欠損
mean30.56 平均値
std15.31 標準偏差(バラつき具合)
min2.0 最小値
25%19.75 第1四分位(下から25%の値)
50%26.50 中央値(メジアン)
75%37.25 第3四分位(上から25%の値)
max54.0 最大値
describe() — Age 列の分布イメージ min 2 25% 19.8 中央値 50% 26.5 平均 30.6 75% 37.3 max 54 IQR (中央50%) 中央値 平均(外れ値で引っ張られる)

🔎 info() — Non-Null Count で欠損を見る

各列の Non-Null Count(欠損ゼロ行数)を棒グラフで表現しています。全10行中、赤い列に欠損があります。

PassengerId
10 / 10
Survived
10 / 10
Pclass
10 / 10
Name
10 / 10
Sex
10 / 10
Age ← 欠損!
8 / 10
SibSp
10 / 10
Parch
10 / 10
Fare
10 / 10

緑 = 欠損なし(10/10) | 赤 = 欠損あり(8/10)

📝 問題

📌
シナリオ: 以下のCSVデータを読み込み、shape / dtypes / describe / info を使った4つの確認タスクを実装してください。
import pandas as pd
import io

csv_data = """PassengerId,Survived,Pclass,Name,Sex,Age,SibSp,Parch,Fare
1,0,3,Braund Mr. Owen Harris,male,22.0,1,0,7.25
2,1,1,Cumings Mrs. John Bradley,female,38.0,1,0,71.28
3,1,3,Heikkinen Miss. Laina,female,26.0,0,0,7.92
4,1,1,Futrelle Mrs. Jacques Heath,female,35.0,1,0,53.1
5,0,3,Allen Mr. William Henry,male,,0,0,8.05
6,0,3,Moran Mr. James,male,,0,0,8.46
7,0,1,McCarthy Mr. Timothy J,male,54.0,0,0,51.86
8,0,3,Palsson Master. Gosta Leonard,male,2.0,3,1,21.07
9,1,3,Johnson Mrs. Oscar W,female,27.0,0,2,11.13
10,1,2,Nasser Mrs. Nicholas,female,14.0,1,0,30.07
"""

df = pd.read_csv(io.StringIO(csv_data))

タスク1 — shape で行数・列数を取得

df.shape を使って「行数と列数」を表示し、変数 n_rows, n_cols に格納してください。

💡
期待する出力: 行数=10, 列数=9

タスク2 — dtypes で文字列列を抽出

df.dtypes を使って「文字列型(object)の列名」をリスト str_cols に格納してください。

💡
期待する出力: ['Name', 'Sex']

タスク3 — describe() で Age の統計を取り出す

df.describe() を使い、以下の2つを変数に格納してください。

  • age_mean: Age 列の平均
  • age_missing: Age 列の欠損数(総行数 - count)

タスク4 — info() を実行して欠損列を確認

df.info() を実行し、Non-Null Count が全行数より少ない列(= 欠損あり)を目視で確認してください。

💡
コードは df.info() の1行だけでOKです。出力の読み方を確認しましょう。

🔍 ヒント(段階的開示)

ヒント1 — 方向性
  • タスク1: df.shape はタプル。n_rows, n_cols = df.shape でアンパック
  • タスク2: df.dtypes は Series。df.dtypes == "object" で True/False 絞り込み
  • タスク3: df.describe() は DataFrame。.loc["mean", "Age"] で特定値を取得
  • タスク4: df.info() を呼ぶだけ。Non-Null Count が 10 未満の行に注目
ヒント2 — アプローチ
# タスク1
n_rows, n_cols = df.shape

# タスク2
str_cols = df.dtypes[df.dtypes == "object"].index.tolist()

# タスク3
stats = df.describe()
age_mean = stats.loc["mean", "Age"]
age_missing = df.shape[0] - int(stats.loc["count", "Age"])

# タスク4
df.info()
ヒント3 — コード骨格(ほぼ答え)
# タスク1
n_rows, n_cols = df.___
print(f"行数: {n_rows}, 列数: {n_cols}")

# タスク2
str_cols = df.___[df.___ == ___].index.tolist()

# タスク3
stats = df.___()
age_mean    = stats.loc[___, ___]
age_missing = df.shape[0] - int(stats.loc[___, ___])

# タスク4
df.___()

模範解答

import pandas as pd
import io

csv_data = """PassengerId,Survived,Pclass,Name,Sex,Age,SibSp,Parch,Fare
1,0,3,Braund Mr. Owen Harris,male,22.0,1,0,7.25
2,1,1,Cumings Mrs. John Bradley,female,38.0,1,0,71.28
3,1,3,Heikkinen Miss. Laina,female,26.0,0,0,7.92
4,1,1,Futrelle Mrs. Jacques Heath,female,35.0,1,0,53.1
5,0,3,Allen Mr. William Henry,male,,0,0,8.05
6,0,3,Moran Mr. James,male,,0,0,8.46
7,0,1,McCarthy Mr. Timothy J,male,54.0,0,0,51.86
8,0,3,Palsson Master. Gosta Leonard,male,2.0,3,1,21.07
9,1,3,Johnson Mrs. Oscar W,female,27.0,0,2,11.13
10,1,2,Nasser Mrs. Nicholas,female,14.0,1,0,30.07
"""
df = pd.read_csv(io.StringIO(csv_data))

# タスク1: shape
n_rows, n_cols = df.shape
print(f"タスク1: 行数={n_rows}, 列数={n_cols}")
# → タスク1: 行数=10, 列数=9

# タスク2: 文字列列の抽出
str_cols = df.dtypes[df.dtypes == "object"].index.tolist()
print(f"タスク2: 文字列型の列 → {str_cols}")
# → タスク2: 文字列型の列 → ['Name', 'Sex']

# タスク3: describe() から Age の統計
stats = df.describe()
age_mean    = stats.loc["mean", "Age"]
age_missing = df.shape[0] - int(stats.loc["count", "Age"])
print(f"タスク3: Age 平均={age_mean:.2f}, Age 欠損数={age_missing}")
# → タスク3: Age 平均=30.56, Age 欠損数=2

# タスク4: info()
df.info()
# Data columns (total 9 columns):
#  #   Column       Non-Null Count  Dtype
#  5   Age           8 non-null     float64  ← 欠損あり!

🪜 Step-by-Step 解説

1 pd.read_csv() でデータを読み込む

実際のKaggleでは pd.read_csv("train.csv") とファイルパスを渡します。io.StringIO() は文字列をファイルのように扱うPython標準ライブラリです(練習環境用)。

2 shape はタプル — アンパックで一発格納

n_rows, n_cols = df.shape   # (10, 9) をアンパック

df.shape(行数, 列数) のタプルを返します。Pythonのアンパック構文で2変数に一行で代入できます。括弧は不要(属性)です。

3 dtypes から "object" 列を絞り込む

str_cols = df.dtypes[df.dtypes == "object"].index.tolist()

df.dtypes → 各列の型が値の Series
df.dtypes == "object" → True/False の Series
[True/False Series] → True の行だけ取り出す(ブールインデックス)
.index.tolist() → 列名のリストに変換

4 describe() の結果は DataFrame — .loc で値を取り出す

stats = df.describe()
age_mean = stats.loc["mean", "Age"]
age_missing = df.shape[0] - int(stats.loc["count", "Age"])

describe() の出力は「行ラベル = 統計量名、列 = 元の列名」のDataFrameです。count は欠損を除いた有効行数なので、総行数との差が欠損数になります。

5 info() の読み方 — Non-Null Count に注目

df.info()
# ...
# 5   Age   8 non-null  float64   ← 10行中8行のみ有効 = 2件欠損

全列のうち「Non-Null Count が総行数より少ない列」が欠損ありです。describe() の count よりも一覧で確認しやすいため、EDAの最初に必ず実行します。

🔢 数学・統計の補足(文系向け)

describe() の8行は「5数要約+α」

統計学には「5数要約」という概念があり、データの分布を5つの数字で表します。

最小値(min) → 25%点 → 中央値(50%) → 75%点 → 最大値(max)

describe() はこれに count(有効数)・mean(平均)・std(標準偏差)を加えた8行を返します。

平均と中央値がずれる理由

Age の平均(30.56)は中央値(26.5)より高いです。これは54歳という大きな値が平均を引き上げているためです。このような「外れ値のある分布」では中央値のほうが代表値として適切な場合があります。

shape の (10, 9) はエクセルの「行列数を数える」感覚

スプレッドシートでデータを開いたとき「10行9列のデータだ」と確認するのと全く同じです。Kaggleでは数万〜数百万行が当たり前なので、まず shape で規模感を把握します。

🏆 Kaggleでの実践的な使い方

Kaggleコンペの「最初の3分」のルーティンとして、そのまま使えるテンプレートです。

import pandas as pd

train = pd.read_csv("train.csv")
test  = pd.read_csv("test.csv")

# ① 規模確認
print("Train shape:", train.shape)
print("Test shape: ", test.shape)
print()

# ② 型確認
print(train.dtypes)
print()

# ③ 統計量確認(欠損・外れ値の有無)
print(train.describe())
print()

# ④ 欠損の全体像
train.info()
確認項目意図
shapeデータ規模を把握(特徴量エンジニアリングの方針に影響)
dtypes数値列・カテゴリ列を分類(エンコーディング計画)
describe()外れ値・欠損の有無を一目で把握
info()欠損がある列を全列まとめて確認

⚠️ よくある誤解・ミス

誤解・ミスなぜ起こるか正しい理解
df.shape() と括弧をつける メソッドと混同 shape は属性(プロパティ)なので括弧不要。df.describe() のような呼び出しとは異なる
describe() に文字列列が含まれない 仕様を知らない デフォルトで数値列のみ。df.describe(include="all") で全列表示できる
dtypes == str と書く Pythonの型とpandasの型を混同 pandasの文字列型は "object" という文字列で比較する。str ではない
describe()count を全行数と思い込む 欠損の概念を知らない count は「欠損を除いた有効行数」。総行数より少なければ欠損あり。全行数は shape[0]
整数列なのに float64 で驚く 欠損とデータ型の関係を知らない pandasは整数に欠損(NaN)を格納できないため、欠損を含む整数列は自動で float64 になる

🚀 次のステップ

  • 発展: df.isnull().sum() で欠損数を列ごとに一覧取得 → 欠損可視化(ヒートマップ)
  • 次回予告: 欠損値の確認と対処(isna, fillna, dropna

📋 自己評価(解いた後に記入)

自分の回答・気づき・メモ: