論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
ピボットテーブル
Pivot Table
データ処理

🔖 キーワード索引

クロス集計Excelpandaspivot_tablegroupby集約関数行/列の入替stackunstackピボットチャート

別名・略称:(なし)

ピボットテーブル は行・列・値を動的に組み替えて集計するクロス集計表で、 Excel/Power Query/pandas.pivot_table で実装される。 SSDSE-B-2026 を「年度 × 都道府県 × 指標」でピボットし、 2015→2023 年の人口推移マトリックスを生成する。

pivot table統計分析SSDSE-B-2026前提条件適用範囲落とし穴関連手法Python 実装検証方法

これらのキーワードは「pivot table の理解 → 適用 → 検証」のプロセスを構成する。 各章で詳しく解説する。

💡 30秒で分かる結論

🍰 まずはやさしく

データの整理整頓をする魔法の道具です。

複雑なデータを分かりやすい表にするために使います。

部活の出席簿を月ごとの表にまとめるようなものです。

この機能でできることの結論を学びます。

ピボットテーブル(Pivot Table):クロス集計と再集計を行う Excel/Pandas 機能

📍 あなたが今見ているもの

🍰 まずはやさしく

データの見た目を変える操作のことです。

レポート作成やデータの分析に役立てます。

スマホの利用時間を曜日ごとの表にするイメージです。

具体的な使い方と学習の流れを説明します。

「都道府県 × 年 × 消費支出」のような 多次元データ を、 「行=都道府県、 列=年、 セル=消費支出平均」という見やすい表に変える操作がピボット。 Excel が代表的ですが、 pandas でも全く同じことが可能。 レポート作成・データ探索の基本道具 です。

本ページは ピボットテーブル を、 SSDSE-B-2026 の縦持ち (long) データを年度×都道府県の横持ち (wide) 行列に変換する操作として実装する。 pandas.pivot_table の index/columns/values/aggfunc を Excel ピボット UI と対応付け、 集計関数 (sum/mean/count) の選択が結果をどう変えるかを確認する。

「pivot table」は統計・データサイエンスの体系における重要概念のひとつ。 本ページは「定義・直感・数式・実装・落とし穴・関連手法」の 6 視点で構成され、 各視点は独立して読めるが順序通り読むと体系的な理解が得られる。

🎨 直感で掴む

🍰 まずはやさしく

表の縦と横を入れ替えるパズルのようなものです。

データの変化をひと目で比べるために使います。

テストの点数を科目ごとの表に並べ替える感覚です。

表がどう変わるのかを直感的に理解しましょう。

ピボット前後の比較 (SSDSE-B-2026 A1101 総人口、 万人単位)

Before(縦持ち, long format):SSDSE-B-2026 はこの形で配布される

都道府県A1101 (人)
東京都202114,010,000
東京都202214,038,000
東京都202314,086,000
大阪府20218,806,000
大阪府20228,782,000
大阪府20238,763,000

After(ピボット後、 wide format):年次比較や前年差計算がしやすい

都道府県\年2021202220233 年変化
東京都14,010,00014,038,00014,086,000+76,000
大阪府8,806,0008,782,0008,763,000-43,000

3 つの判断: ① pivot は「列が観測の 属性 ではなく 値そのもの になる」 (year 2021/2022 が列名に昇格) — Wickham (2014) tidy 原則とは逆向きの整形だが、 集計表 / 棒グラフ用には有用。 ② 欠損 (例: 集計しきれない県年の組合せ) は NaN として埋められる。 ③ aggfunc を指定すれば「都道府県 × 年」セルに sum / mean / count 等を入れ、 SSDSE-B-2026 の人口を地方区分 (関東/近畿…) で集計し直す重集計ができる。

📐 定義 / 数式

🍰 まずはやさしく

集計のルールを決めるための仕組みです。

計算方法を正しく指定して表を作るために使います。

買い物リストから合計金額を出す計算に似ています。

表を作るための設定項目について詳しく学びます。

【ピボットテーブルの一般形】
$$\text{pivot}(\text{data}, \text{index}, \text{columns}, \text{values}, \text{aggfunc})$$
  • index: 行に置くキー
  • columns: 列に置くキー
  • values: セルに集約する値
  • aggfunc: 集約関数(sum, mean, count, ...)

🔬 記号・式を言葉で読み解く

index
ピボットテーブルの「行」になる変数。 例: 都道府県
columns
「列」になる変数。 例: 年
values
セルに入る値。 例: 消費支出
aggfunc
重複した場合の集約方法。 sum, mean, count, median, max, min など
margins
合計行・列を追加するか。 True で全体合計が付加

🧮 SSDSE-B-2026 で実データ計算

SSDSE-B-2026 の構造

SSDSE-B-2026 は 47 都道府県 × 12 年度 = 564 行、 112 変数の縦持ち構造。 ピボットの対象として理想的な大きさ。

手計算例 1:地方ブロック × 指標のピボット (合計)

2023 年 47 都道府県を 8 地方ブロックに分けて、 「総人口・65 歳以上人口・消費支出」を合計集計:

ピボット結果 (index=地方, values=各指標, aggfunc='sum'): 地方 65歳以上人口 消費支出(二人以上世帯) 総人口 中国 2,263,000 1,460,752 7,070,000 中部 6,161,000 2,745,302 20,749,000 九州沖縄 4,291,000 2,233,623 14,029,000 北海道 1,681,000 296,888 5,092,000 四国 1,230,000 1,106,113 3,578,000 東北 2,790,000 1,769,712 8,318,000 近畿 6,423,000 2,077,281 21,990,000 関東 11,390,000 2,215,562 43,527,000 行集計 (margins=True): 合計 36,229,000 13,905,233 124,353,000

関東地方 (1 都 6 県) で総人口の 35% (43,527 / 124,353)、 65 歳以上の 31% を占める。 「地方ブロック × 指標」のピボットは政策資料・新聞解説でよく使われる典型構造。

手計算例 2:地方 × 年度のピボット (合計特殊出生率の平均)

2020-2023 年の地方ブロック別平均出生率を「行=地方 × 列=年度」のピボット表で:

ピボット結果 (index=地方, columns=年度, values=合計特殊出生率, aggfunc='mean'): 年度 2020 2021 2022 2023 地方 中国 1.512 1.498 1.486 1.390 中部 1.443 1.414 1.387 1.321 九州沖縄 1.606 1.594 1.539 1.455 北海道 1.210 1.200 1.120 1.060 四国 1.445 1.450 1.405 1.342 東北 1.308 1.277 1.218 1.165 近畿 1.370 1.353 1.311 1.257 関東 1.281 1.241 1.199 1.151

全地方で 2020 → 2023 にかけて出生率が低下している。 一目で時系列トレンドが把握できるのがピボットの威力。 「九州沖縄」が常に最高、 「北海道」が最低という地理的構造も見える。

手計算例 3:行 × 列の入れ替え (転置)

同じデータを「行=年度、 列=地方」に入れ替えると:

年度 中国 中部 九州沖縄 北海道 四国 東北 近畿 関東 2020 1.512 1.443 1.606 1.210 1.445 1.308 1.370 1.281 2021 1.498 1.414 1.594 1.200 1.450 1.277 1.353 1.241 2022 1.486 1.387 1.539 1.120 1.405 1.218 1.311 1.199 2023 1.390 1.321 1.455 1.060 1.342 1.165 1.257 1.151

同じ情報だが、 「年度間比較」が主目的なら左側 (前の表)、 「地方間比較」が主目的ならこちら (転置表) のほうが読みやすい。 行と列の選択は「何を比較したいか」で決める。

🧮 aggfunc 多段集計と margins (SSDSE-B-2026)

pivot_table の真の威力は 「複数の集計関数を同時に適用」「margins (合計行・列)」。 数式を言葉で読み解くと、 セル値 = aggfunc(values[行条件 ∧ 列条件])。 margins=True で全体集計を一気に取得できる。

🎯 このコードでやること:地域 × 年度 で人口の mean / median / std / count を同時集計し、 margins で全体合計も併記する。

📥 入力データ:SSDSE-B-2026 を long 形式に整形 (都道府県, 地域, 年度, 人口)。 地域 8 区分 (北海道/東北/関東/中部/近畿/中国/四国/九州沖縄)、 12 年分で 564 行。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import pandas as pd

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1)
region_map = {'北海道':'北海道','青森県':'東北','岩手県':'東北','宮城県':'東北',
    '秋田県':'東北','山形県':'東北','福島県':'東北','茨城県':'関東','栃木県':'関東',
    '群馬県':'関東','埼玉県':'関東','千葉県':'関東','東京都':'関東','神奈川県':'関東',
    '新潟県':'中部','富山県':'中部','石川県':'中部','福井県':'中部','山梨県':'中部',
    '長野県':'中部','岐阜県':'中部','静岡県':'中部','愛知県':'中部','三重県':'近畿',
    '滋賀県':'近畿','京都府':'近畿','大阪府':'近畿','兵庫県':'近畿','奈良県':'近畿',
    '和歌山県':'近畿','鳥取県':'中国','島根県':'中国','岡山県':'中国','広島県':'中国',
    '山口県':'中国','徳島県':'四国','香川県':'四国','愛媛県':'四国','高知県':'四国',
    '福岡県':'九州沖縄','佐賀県':'九州沖縄','長崎県':'九州沖縄','熊本県':'九州沖縄',
    '大分県':'九州沖縄','宮崎県':'九州沖縄','鹿児島県':'九州沖縄','沖縄県':'九州沖縄'}
long = df[['都道府県', '年度', '総人口']].copy()
long['地域'] = df['都道府県'].map(region_map)
long = long.rename(columns={'総人口': '人口'})  # 県×年の long 形式(564 行)
print(long[['都道府県', '地域', '年度', '人口']].head(3))

# aggfunc に list を渡せば、複数の集計を同時に計算できる
pt = pd.pivot_table(
    long,
    index='地域',
    columns='年度',
    values='人口',
    aggfunc=['mean', 'median', 'std', 'count'],
    margins=True,
    margins_name='全国'
)
print(pt.loc[:, [('mean', 2012), ('median', 2012),
                 ('std', 2012), ('count', 2012)]].round(0))  # 2012 年列だけ抜粋

📤 実行例

mean median std count 年度 2012 2012 2012 2012 地域 中国 1503400.0 1434000.0 935340.0 5 中部 2401444.0 2062000.0 2106861.0 9 九州沖縄 1819750.0 1409500.0 1356300.0 8 北海道 5465000.0 5465000.0 NaN 1 四国 982500.0 882000.0 307542.0 4 東北 1526333.0 1328000.0 502681.0 6 近畿 3242143.0 1841000.0 2921622.0 7 関東 6093286.0 6200000.0 4176248.0 7 全国 2714660.0 1687000.0 2693848.0 47

💬 結果の読み方:北海道は 1 県のみなので std=NaN。 関東は平均 609 万・中央値 620 万・標準偏差 418 万(東京 1323 万という突出県を含む)。 mean・median・std を併記することで「典型的な関東県の規模」と「ばらつきの大きさ」を同時に読める。 単一の mean だけ報告するのは情報の損失。

📝 より正確な分析:実測 2012 年の関東では 中央値 620 万 > 平均 609 万 となり、 教科書的な「外れ値が平均を吊り上げて mean > median」とは逆向きになる。 関東は東京だけでなく神奈川・埼玉・千葉と大人口県を複数抱えるため、 中央値も高く保たれるからだ。 「東京の外れ値が代表値を歪める」効果がはっきり出るのは 全国 47 県の集計(平均 271 万 ≫ 中央値 169 万)で、 地域内 7 県では必ずしも成立しない。 mean と median の大小は分布とサンプル構成で決まるので、 実データでは必ず両方を確認する。

🐍 vs groupby — どちらを使うべきか

🎯 このコードでやること:同じ集計を pivot_tablegroupby.unstack で実行し、 結果と速度を比較。

📥 入力データ:上の long DataFrame (564 行)。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import time

# 方式 A: pivot_table
t0 = time.perf_counter()
for _ in range(1000):
    pt_a = pd.pivot_table(long, index='地域', columns='年度',
                          values='人口', aggfunc='mean', fill_value=0)
ta = (time.perf_counter() - t0) * 1000

# 方式 B: groupby + unstack
t0 = time.perf_counter()
for _ in range(1000):
    pt_b = long.groupby(['地域', '年度'])['人口'].mean().unstack(fill_value=0)
tb = (time.perf_counter() - t0) * 1000

print(f'pivot_table     : {ta:.0f} ms / 1000回')
print(f'groupby+unstack : {tb:.0f} ms / 1000回')
print(f'結果一致        : {(pt_a == pt_b).all().all()}')

📤 実行例

pivot_table … 反復 1000 回で およそ 3〜5 秒 groupby+unstack … 反復 1000 回で およそ 1〜2 秒 結果一致 : True ※ 実測のミリ秒は環境で変わる。 読むべきは「groupby+unstack が pivot_table の 約 3 分の 1 の時間で同じ結果を返す」という比のほう。

💬 結果の読み方:結果は完全一致だが、 速度は groupby+unstack の方が約 1.75 倍速い。 pivot_table は内部で groupby を呼び、 さらに margins や fill_value、 多 aggfunc のための追加処理を行うため遅い。 「margins/多 aggfunc/欠損穴埋めを使う」なら pivot_table、 「速度優先・シンプル集計」なら groupby

⚠️ pivot vs pivot_table vs crosstab の使い分け

関数aggfunc重複キー用途
df.pivotなしエラー一意キーの単純な行列変換
pd.pivot_table指定可能 (default mean)集計数値列の集計・多段集計・margins
pd.crosstabdefault count集計頻度表 (normalize='index' で割合)

核心:「人口を地域×年度で平均」なら pivot_table、 「都道府県を地域×サイズクラスで件数」なら crosstab、 「すでに集計済みデータを wide にするだけ」なら pivot。 SSDSE-B-2026 を題材にこの 3 種を 常に使い分けられること がデータ整形の核心スキル。

🔭 ピボットテーブルを「視覚的に」徹底解剖する(視覚化深堀り)

ピボットテーブルは数表として完結しているように見えるが、 実際には「集計後の数値がどんな分布をしているか」「カテゴリごとの差はどの程度か」「時間軸でどう動いているか」「集計列どうしがどう相関しているか」を 必ず可視化と組み合わせて読む べきである。 本章では SSDSE-B-2026 を題材に、 ピボットテーブルから派生する 4 タイプの可視化を順に解説する。 単に図を貼るのではなく、 各図が「ピボットテーブルのどの列を、 どう変形して、 何を見せようとしているか」を逐一言葉にすることで、 読者が 自分のデータで同じ流れを再現できる 状態を目指す。

視覚化 1:地域別「都道府県数」の集計を散布図で確かめる

ピボットテーブルで「地域 × 都道府県数」を集計すると、 北海道・東北は 7、 関東は 7、 中部は 9、 近畿は 7、 中国・四国は 9、 九州沖縄は 8 のように単純な度数表が得られる。 これを「人口」と組み合わせ、 各都道府県の 人口対面積を散布図で確認することで、 ピボットの背後にある「47 行のミクロな観測」を再認識できる。 数表だけ眺めていると 47 県の差異が消える危険があるが、 散布図で 47 点を可視化すると「同じ関東地方の中でも東京都と山梨県は極端な差がある」ことが一目で分かる。

SSDSE-B-2026 都道府県散布図 (ピボット元データの分布確認)

図 R347-1:ピボット集計の 元データ(47 都道府県の 2 変数分布)。 集計後の地域別平均だけを見ると、 各地域内のばらつきが消えてしまう。 pivot_table(..., aggfunc=['mean','std','min','max']) のように複数集計関数を並べることで、 散布図に現れている「同地域内格差」を数値で再現できる。

散布図の右上に位置する都道府県(例えば北海道のように面積が極端に大きい、 あるいは東京のように人口が極端に多い)は、 ピボットの mean を強く引き上げる「梃子点」になる。 したがって地域別平均を読むときは「平均がこの値だが、 内訳の最大値はその 3〜5 倍ある」という補足を必ず添える必要があり、 そのために aggfunc=['mean','max'] を併記したピボットを作るのが定石である。

視覚化 2:集計値の分布をヒストグラムで眺める

ピボットテーブルの「行 = 都道府県、 列 = 指標」というレイアウトから 1 列を取り出して描くヒストグラムは、 「47 県という固定母集団の中で値がどう散らばっているか」を把握する最も基本の可視化である。 平均値や中央値だけでは「右裾が長いか」「ゼロ近傍に山があるか」「双峰性があるか」を見落とすが、 ヒストグラムを描けば一瞬で判断できる。 SSDSE-B-2026 の総人口を 47 県で描けば「東京・神奈川・大阪が右端に孤立し、 中央値は 150〜200 万人帯にある」という典型的な右裾分布が見える。

ピボット集計列のヒストグラム (47 都道府県の度数分布)

図 R347-2:ピボットテーブルから取り出した数値列のヒストグラム。 集計の aggfunc='mean' は分布の山が左右対称なときには適切だが、 右裾が長いときには 'median' を併用しないと典型値を過大評価する。 ヒストグラムを必ず描いて「平均と中央値の乖離」を確認する習慣が、 ピボット運用の安全装置になる。

ヒストグラムを描いた結果、 強い右裾を持つことが判明したら、 ピボットの集計関数を ['mean','median','std'] の三点セットに切り替えるか、 値そのものに log1p 変換を施してから集計するという二つの選択肢が生まれる。 どちらが正しいかは「平均値を経済指標として示したいか」「分布の中心位置を比較したいか」という目的次第である。 ピボットテーブルは「数値列を 1 つの代表値に潰す装置」であるため、 潰す前にヒストグラムで分布形状を確認する工程は省略してはならない。

視覚化 3:カテゴリ別の分布を箱ひげ図で比較する

ピボットテーブルの「行 = 地域、 列 = 指標」という見せ方は、 各セルが代表値 1 つに圧縮されているため「地域内のばらつき」が見えない。 これを補うのが箱ひげ図である。 横軸に 7 つの地域、 縦軸に対象指標を取り、 各地域に属する都道府県の値を箱ひげで重ねれば、 ピボットの「地域別平均」が「地域内中央値・四分位範囲・外れ値」とどう一致しているか/していないかを 1 図で診断できる。

地域別の箱ひげ図 (ピボット代表値とばらつきの照合)

図 R347-3:地域カテゴリ別の箱ひげ図。 ピボットの mean セルは点ではなく、 箱の上端付近に位置することが多い(外れ値に引かれるため)。 箱ひげ図と pivot_table(aggfunc='median') を併記すると、 「平均は外れ値の影響、 中央値は典型値」という二段構えの読みが成立する。

箱ひげ図から「ある地域だけ箱が極端に高い・低い」「外れ値が片側に集中している」といったパターンが見えたら、 ピボットの並び替え戦略を変更する余地がある。 たとえば pivot_table(values='人口', index='地域', columns='年度', aggfunc='median') のように中央値で集計し直す、 あるいは margins=True で全体平均を行末に追加して「全体に対する地域の偏差」を計算するなど、 図から得た示唆をピボットの引数に反映する循環が、 ピボット運用の品質を一段引き上げる。

視覚化 4:集計列どうしの相関を 4×4 ヒートマップで把握する

ピボットテーブルの「行 = 都道府県、 列 = 複数指標(人口・面積・財政・産業 など)」が完成したら、 次に行うべきは 列間相関の確認である。 df_pivot.corr() で計算した相関行列をヒートマップで描けば、 「どの指標とどの指標が連動しているか」「独立に見えても実は人口を介して相関しているか」「集計後でも符号が変わらないか」が一望できる。 4 指標を選んで描く 4×4 ヒートマップは、 ピボットの結果を「次に何の分析につなげるか」を決める出発点になる。

ピボット集計後の 4 指標相関ヒートマップ

図 R347-4:ピボット後の 4 指標相関行列。 集計前のレコード単位相関と、 集計後の都道府県単位相関は 必ずしも一致しない。 集計レベルが上がると相関は強まる傾向(Ecological correlation)があり、 同じデータでも個人レベルと都道府県レベルで相関係数が 0.4 → 0.8 のように激変することが珍しくない。

ピボットテーブルで集計してからヒートマップを描く運用は、 多くの BI ツール(Tableau、 Power BI、 Looker など)の「探索的分析ループ」と完全に対応する。 集計レベルを変えるたびに相関行列が変化するため、 「都道府県別」「市区町村別」「年度別」など複数粒度のヒートマップを並べて見比べると、 ピボットの粒度選択が分析結論にどれだけ影響するかを直感的に理解できる。 結果として「ピボットの index と columns の選択は、 仮説の半分を決める設計判断である」という認識に到達する。

📝 視覚化を伴うピボット運用チェックリスト

タイミング描くべき図確認する観点図が示唆する次のピボット操作
ピボット作成前散布図/ヒストグラム分布形状・外れ値・歪度aggfunc を mean か median か decide/log 変換の要否
ピボット作成直後箱ひげ図カテゴリ内ばらつき・外れ値の偏り代表値を mean/median 併記/std 列追加
複数指標を並べた後4×4 ヒートマップ指標間相関・冗長性・潜在因子主成分分析・特徴量選択/集計粒度の再検討
時系列ピボット折れ線(時系列図)トレンド・季節性・構造変化差分・ローリング平均列を追加
レポート提出前全 4 図を並列表示数表と図の整合性読者の誤読リスクを潰す注釈を追加

視覚化 5:時系列ピボットを折れ線で読む

ピボットテーブルが時系列データを扱う場合、 「行 = 都道府県、 列 = 年度、 値 = 人口」のような wide 形式に変形した上で、 行から数本を取り出して折れ線図を描くのが定番の手順である。 折れ線図はピボットの cells をそのまま線で結ぶ操作に等しく、 ピボットを描くこと自体が「複数都道府県の時系列を同一軸で比較するための前処理」になる。 SSDSE-B-2026 を 2010 → 2026 年度で並べれば、 東京の継続増・地方圏の減少という「人口の地殻変動」が一目で読み取れる。

ピボット (年度別) を折れ線で可視化した時系列図

図 R347-5:時系列ピボット pivot_table(values='人口', index='年度', columns='都道府県') を折れ線で描いた図。 ピボットの形状(年度 × 都道府県)はそのまま折れ線の軸割り当てに対応し、 「行で時間を流す」「列で対象を並べる」という設計が時系列比較のために最適化されていることが分かる。

時系列ピボットには「fill_value=0 で欠損年度を埋めるか」「reindex(range(2010, 2027)) で欠損年度をそもそも作るか」という設計選択がある。 折れ線図で見ると、 fill_value=0 を選んだ年度だけ突如線が地面に落ちる現象が起き、 これが分析者を「人口がゼロになった」と誤読させる重大なリスクであることが直感的に分かる。 数表段階では気付かなかった欠損処理の不適切さが、 折れ線という単純な可視化で即座に露呈する。

🧪 演習:ピボット視覚化を自分で動かして読む

問 1(基本):SSDSE-B-2026 から pivot_table(values='総人口', index='地域', aggfunc=['mean','median','std','count']) を作成せよ。 続けて、 同じ地域分類を横軸にした箱ひげ図を描き、 ピボットの mean と median が箱の中でどこに位置するかを確認せよ。 mean と median の大小関係が逆転している地域があれば、 その地域名と、 なぜ逆転が起きたかを 80 字以内で説明せよ。

解答の方針を表示

SSDSE-B-2026 の 2023 年総人口では、 全国 47 県が平均 265 万 ≫ 中央値 155 万で、 東京など大都市の右裾が平均を強く引き上げる典型例。 一方 関東 7 県だけを取り出すと東京・神奈川・埼玉・千葉と大人口県が複数あるため中央値も高く、 平均 622 万 ≲ 中央値 626 万とむしろ僅かに逆転する。 mean > median は「右裾の外れ値が引き上げる」サイン、 mean < median は「左裾の例外が引き下げる」サインだが、 大小はサンプル構成で変わるため、 箱ひげ図で median と mean の位置関係を必ず確認するのが要点。

問 2(応用):SSDSE-B-2026 から 4 つの指標(総人口、 65 歳以上人口、 年平均気温、 消費支出(二人以上の世帯))を選び、 pivot_table(index='都道府県', values=[...4指標...], aggfunc='sum') で集計せよ。 続けて .corr() でヒートマップを描き、 「集計前のレコード単位相関」と「集計後の都道府県単位相関」を比較する手順を 5 ステップで書け(疑似コード可)。 さらに、 もし両者が大きく異なった場合、 どちらをレポートに採用すべきかを 100 字以内で論じよ。

解答の方針を表示

ステップは ①レコード単位で df[cols].corr() を計算 → ② ピボット後 df_p.corr() を計算 → ③ seaborn.heatmap で 2 図並べて描画 → ④ 差分行列 (df_p.corr() - df.corr()) を計算 → ⑤ 差が 0.3 を超えるペアを抽出。 採用判断は「分析の意思決定単位」に従う:都道府県単位の政策議論なら集計後、 個別事業所評価ならレコード単位を採用する。 両者を併記し「集計レベルにより相関が変化する」と注釈するのが最も誠実。

問 3(実践):時系列ピボット pivot_table(values='総人口', index='年度', columns='地域', aggfunc='sum') を SSDSE-B-2026 から作成し、 折れ線図で 7 地域の人口推移を描け。 続けて、 各地域の人口を「2010 年度 = 100」に正規化した折れ線図を別に描き、 元の折れ線図と比較して「規模を見るときと変化率を見るときで読み取れる結論はどう違うか」を 120 字以内で論じよ。 さらに、 ピボットの aggfunc'sum' から 'mean' に変えた場合、 折れ線の上下関係が変わるかどうかを確認し、 変わる場合の理由を述べよ。

解答の方針を表示

絶対値で見れば関東が圧倒的トップで他地域が密集して見えるが、 2010 年度=100 で正規化すると「関東は微増、 北海道・東北・中国・四国は急減」という相対的な縮減ペースの違いが鮮明になる。 政策判断には正規化版が、 規模感の把握には絶対値版が向く。 aggfunc='sum''mean' に変えると「地域あたりの都道府県数」で割ることになり、 都道府県数が多い中部地方が相対的に下がり、 都道府県数が少ない北海道が単独で上がるなどの順位逆転が起きる。 集計関数の選択は折れ線の意味そのものを変えることを示せれば満点。

🧩 ピボットテーブル設計のアンチパターン 10 連発

実務でピボットテーブルを長く触っていると、 同じ失敗が何度も繰り返されることに気付く。 ここでは「やってしまいがちな 10 のアンチパターン」を一気に並べ、 それぞれに対する具体的な処方箋を示す。 1 つでも心当たりがあれば、 既存ピボット運用のレビュー対象である。

#アンチパターン具体例処方箋
1aggfunc を省略気付かず mean になっていて 中央値派の上司と齟齬必ず明示的に指定し、 mean か median か事前合意
2欠損 NaN を 0 で埋める「未測定」と「0 件」が同じ表現で混同fill_value は使わず、 NaN を残して可視化段階で区別
3columns に高カーディナリティ列市区町村 1700 列の wide 表で計算停止columns は 20 以下を上限とし、 上位 N+others にまとめる
4margins と percent の混在margins=True と normalize='index' を同時に指定して合計が 100% に近いが微妙にずれるmargins は合計、 normalize は割合と役割が違う。 同時指定は禁止
5時系列ピボットで欠損年度2014 年度のみ抜けていて折れ線が斜めに繋がるreindex で完全な年度列を作り、 NaN で穴を可視化
6多段 index を flatten せず保存Excel に貼ると 1 行目が空でレイアウト崩壊.reset_index() と .columns.map('_'.join) で平坦化
7小数点丸めをピボットで実施表示用の round 値で次の計算に進み合計が合わない丸めは「最終表示直前」のみ、 計算中は生値を維持
8単位を列名に書かない「人口」列が人数か千人か不明列名末尾に [人]/[千人]/[%] を必ず付与
9無条件で 4 重 index を作る地域×都道府県×年度×月の 4 段で読めずindex は 2 段、 columns は 2 段までを原則とする
10ピボット結果のみ提出「どう作ったか」が再現不能で監査落ち必ず元データ・スクリプト・ピボット引数をセットで保管

10 連発の共通課題は「ピボットを 結果として ではなく 過程として 扱う」という意識転換にある。 ピボットは一度作って終わりではなく、 上流の生データ・引数・下流の可視化・解釈とセットで運用される「動的なオブジェクト」である。 アンチパターンの大半は、 この動的性を忘れて静的な表として固定化したときに起きる。 SSDSE-B-2026 のような公的データで日々ピボットを回している研究者は、 上記 10 件のうち少なくとも 3〜4 件は経験しているはずで、 そのたびにこの表を見直して回避策を再徹底するのが現実的な運用フローになる。

📊 ピボット引数別「結果がどう変わるか」早見比較

同じ SSDSE-B-2026 を題材に、 ピボットテーブルの 4 つの代表引数(index、 columns、 values、 aggfunc)を一つだけ変更したとき、 出力テーブルの形・意味・解釈がどう変わるかを横並びで整理する。 これは「自分のデータに何の引数を当てれば狙った視点が得られるか」を考える設計マニュアル代わりになる。

変更点変更前変更後出力テーブルの変化読み方の変化
index都道府県地域(7 区分)47 行 → 7 行に縮約個別比較 → グループ比較に視点が上位化
columnsなし年度単列 → 横長 wideスナップショット → 時系列比較に拡張
values人口[総人口, 65歳以上人口, 消費支出]単指標 → 多指標単一の現象 → 経済社会の多面的比較
aggfuncmean[mean, median, std]1 列 → 3 列に拡張代表値 → 分布の特徴を含む包括的記述
aggfuncsumcount合計値 → 件数経済規模 → サンプル数の検証
marginsFalseTrue合計行・合計列が追加部分のみ → 全体に対する割合計算が可能
fill_valueNaN(既定)0NaN セル → 0 表示欠損明示 → 未測定が「ゼロ」と誤読される危険
dropnaTrueFalse列・行が増える完全データのみ → 欠損カテゴリも保持

この早見表を 1 枚手元に置いておくと、 ピボット作成中に「いま何を変えれば狙いの視点に近付けるか」が即座に判断できる。 とくに aggfuncsum/mean/median/count/std の 5 つは、 同じ index・columns のままでも完全に異なる物語を生む。 1 つのデータについて、 これら 5 種をすべて作成し、 5 つの解釈を並べてレポートに添えるだけで「ピボットを使い切った分析」と評価される水準に到達する。

🛠 実務でのピボット運用フロー(生データ取得 → レポート提出まで)

最後に、 ピボットテーブルを実務で使うときの典型的な 7 ステップフローを示す。 SSDSE-B-2026 を題材にした研究プロジェクトを想定しているが、 一般の業務データにもそのまま適用できる構造になっている。

  1. ステップ 1:生データの粒度を確認。 1 行 = 何の単位か(都道府県、 月、 事業所等)を df.head()df.dtypes で確認。 ここを間違えるとピボット結果の意味が完全に変わる。
  2. ステップ 2:分析の問いを 1 文に書く。 「地域別の人口推移を時系列で比較したい」「都道府県別の経済指標を横断比較したい」など。 問いから index・columns・values・aggfunc の 4 引数が自動的に決まる。
  3. ステップ 3:必要列のみに絞るdf = df[['都道府県','年度','総人口','65歳以上人口','消費支出(二人以上の世帯)']] のように subset することで、 ピボットがメモリと速度の両面で扱いやすくなる。
  4. ステップ 4:ピボットを作るpd.pivot_table(df, index='地域', columns='年度', values='人口', aggfunc='sum', margins=True) のように、 引数すべてを明示する習慣を付ける。 暗黙の既定値に依存しない。
  5. ステップ 5:必ず可視化を 1 図描く。 数表だけで解釈するのではなく、 折れ線・箱ひげ・ヒートマップのいずれかを必ず添える。 可視化なしのピボットは「読めない表」とほぼ同義。
  6. ステップ 6:再現スクリプトを保存。 ピボットの引数を含む Python ファイルを Git で管理する。 6 ヶ月後の自分が同じ表を再生成できる状態を維持。
  7. ステップ 7:注釈付きで配布。 表とともに「集計関数は median、 欠損は NaN のまま保持、 出典は SSDSE-B-2026」のような注釈を必ず添える。 注釈なしのピボットは独り歩きしてやがて誤読される。

この 7 ステップを 1 サイクル踏むのに慣れれば、 業務依頼が来てから 30 分以内に「初回のピボット + 折れ線図 + 再現スクリプト」を成果物として返せるようになる。 これは BI ツールでマウス操作のみに頼っている同僚に対する明確な優位性であり、 Python ピボットの本当の強みである「再現性」と「可視化との連結」の両立がここで活きる。

🔬 ピボット × 統計検定:集計後の値で何をどう検定できるか

ピボットテーブルは「集計値の表」を生むだけでなく、 そのまま統計検定の入口になることが多い。 たとえば「地域別に平均人口が異なるか」を検定したいとき、 ピボットの行は「グループ」、 値は「観測値」となり、 一元配置分散分析(one-way ANOVA)の入力にそのまま流し込める。 ピボット → 検定の流れを意識的に作っておくと、 数表が単なる説明資料から「定量的な意思決定材料」に格上げされる。

ピボットの形代表的な検定適用例注意点
index=地域, values=人口, aggfunc=list一元配置 ANOVA7 地域間で平均人口に差があるか分散の等質性(Levene 検定)を事前確認
index=都道府県, columns=年度対応のある t 検定2010 と 2020 の人口差は有意か同一都道府県を 2 時点で比較するため対応あり
index=地域, columns=サイズ区分(クロス集計)カイ二乗検定地域と都道府県サイズの分布は独立か期待度数 5 未満のセルが多いと Fisher の正確検定に切替
index=都道府県, columns=指標Pearson/Spearman 相関総人口と消費支出の線形関係外れ値(東京)が結果を支配しないか確認
index=地域, values=複数指標多変量分散分析(MANOVA)地域間で複数指標の平均ベクトルが異なるか指標間の多重共線性を事前確認

ピボットから検定への橋渡しでは、 「ピボットの aggfunc が listlambda でグループ別観測値を保持しているか」が決定的に重要である。 既に mean で 1 つの値に潰してしまったピボットからは、 多くの検定が走れない。 「集計のためのピボット」と「検定のためのピボット」を意識的に作り分け、 検定用には観測値リストを保持しておく設計が、 ピボットを統計分析に接続するための基本姿勢である。

🌍 BI ツール各種でのピボット相当機能の対応関係

Python の pivot_table と同じ概念は、 Excel・Tableau・Power BI・Looker・Google スプレッドシート・Metabase など、 ほぼすべての BI ツールに「ピボットテーブル」「ビュー」「マトリックス」「クロス集計」等の名前で存在する。 ツールが変わっても、 index・columns・values・aggfunc の 4 概念さえ理解していれば、 ほぼ同じ表が作れる。 つまり、 Python ピボットを 1 つ完全に習得することは、 すべての BI ツールに転用可能な汎用スキルを獲得することに等しい。

ツール機能名index に相当columns に相当values + aggfunc に相当
Excelピボットテーブル行ラベル列ラベル値 + 値フィールドの設定
Tableauビュー行シェルフ列シェルフメジャー + 集計関数
Power BIマトリックスビジュアル値 (DAX 集計式)
Lookerピボットディメンションピボット指定したディメンションメジャー
Google スプレッドシートピボットテーブル値 + 集計関数の選択
Metabaseサマリービューグループ化列分割集計式
SQLGROUP BY + CASE WHENGROUP BY 列PIVOT 句(一部の DB)/CASE 式SUM/COUNT/AVG 等の集計関数

特に注目すべきは「SQL の GROUP BY + CASE WHEN」が、 概念的にはピボットテーブルの完全なバックエンドになっていることである。 BigQuery、 Snowflake、 PostgreSQL のいずれにも PIVOT 句が用意されており、 pandas の pivot_table を SQL に翻訳して動かすことは、 大規模データを扱う際の標準テクニックである。 つまり、 ピボットテーブルを学ぶことは「データベースを学ぶ」「BI を学ぶ」「Python を学ぶ」のすべての交差点を学ぶことに等しい。

🎓 ピボットを「設計言語」として身につける学習ロードマップ

ピボットテーブルを「単なる集計コマンド」ではなく「データを語るための設計言語」として身につけるには、 段階的な学習が有効である。 以下は SSDSE-B-2026 を題材にした 5 段階ロードマップで、 各段階に到達したか自己評価できる「合格基準」を併記してある。

  1. レベル 1:基本のピボットを作れる。 合格基準 = SSDSE-B-2026 で「地域別の総人口合計」を pd.pivot_table で 1 行のコードで出力できる。
  2. レベル 2:複数集計関数を並列利用できる。 合格基準 = 同じデータで aggfunc=['mean','median','std','count'] を指定し、 4 列同時の表を出力できる。
  3. レベル 3:時系列ピボットを正しく作れる。 合格基準 = 「年度 × 地域」の wide 表を作り、 欠損年度を reindex で補完し、 折れ線で 7 地域を可視化できる。
  4. レベル 4:ピボットと統計検定を連結できる。 合格基準 = 地域別の人口リストをピボットから取り出し、 scipy.stats.f_oneway で一元配置 ANOVA を実行し、 p 値とともに結果を解釈できる。
  5. レベル 5:ピボット設計を文書化できる。 合格基準 = 自分が作ったピボットについて「なぜ index に地域、 columns に年度、 values に人口、 aggfunc に sum を選んだか」を 200 字以内で論理的に説明できる。

レベル 5 まで達成できれば、 ピボットテーブルは「データから物語を引き出すための設計言語」として自分の中に定着している状態である。 ここまで到達した人は、 BI ツールが変わっても、 データセットが変わっても、 同じ思考プロセスで分析を進められる。 SSDSE-B-2026 はオープンデータとして公開されているため、 上記 5 段階を 1 週間〜1 ヶ月の学習計画に分割して取り組むのが現実的で、 完走すれば確実に「ピボットが使える人」と評価される技能が身につく。

🔁 ピボット → 可視化 → 仮説 → 再ピボット の循環事例

最後に、 SSDSE-B-2026 を題材に「ピボット → 可視化 → 仮説生成 → 再ピボット」というデータ分析の核となる循環を 1 サイクル具体的に追体験する。 1 ターンの循環は 10〜15 分で回り、 これを 3〜5 ターン繰り返すと、 当初想定していなかった発見が高確率で出てくる。 ピボットテーブルは「答えを出す装置」ではなく「次の問いを生む装置」であるという視点が、 この循環の核心である。

ターンピボット設計可視化観察・仮説次の問い
1index=地域, values=人口, aggfunc=sum棒グラフ関東が突出関東内部の都府県差はどれくらい?
2関東のみ抽出、 index=都道府県, values=人口棒グラフ東京・神奈川が支配他指標でも同じ支配構造?
3関東のみ、 index=都道府県, values=複数指標, aggfunc=sumレーダーチャート/ヒートマップ面積では栃木・群馬が逆転人口密度ではどうなる?
4関東のみ、 values=人口/面積を計算、 index=都道府県棒グラフ(降順)東京・神奈川が桁違いの密度全国 47 県で密度を比較すると?
5全国、 values=人口/面積, index=都道府県, columns=地域箱ひげ図(地域別)関東が突出、 北海道が最低過去 20 年で密度の差は拡大?

この循環事例から分かるのは、 ピボットテーブルの真価は「1 つの完璧な表」ではなく「相互に派生していく一連の表の連鎖」にあることである。 1 ターン目で全国地域別の総量を確認し、 関東に注目し、 内部分解し、 別指標との関係を確認し、 全国に戻して密度比較に展開する。 各ターンのピボットはわずか 1〜3 行のコード変更で済むが、 その背後には「観察 → 仮説 → 設計」という思考プロセスが必ず挟まっている。 ピボットを書くとき、 引数を 1 つ書き換える前に「いま自分は何を観察したくて、 どんな仮説を確かめたくて、 そのために何の表が必要か」を口に出すか、 紙にメモする習慣を付けると、 分析の質は劇的に上がる。

🧠 ピボットテーブル運用で陥りやすい認知バイアス 5 種

ピボットテーブルは数値の表だが、 それを作る人間の側に認知バイアスがあると、 同じデータから誤った結論を導きうる。 以下 5 種は、 SSDSE-B-2026 のような公的データを扱う研究プロジェクトで頻繁に観察される認知バイアスで、 自分が陥っていないか定期的にチェックする価値がある。

これら 5 種の認知バイアスは、 統計学的な「データの問題」ではなく、 分析者の「思考の問題」である。 ピボットテーブルが強力な装置であるがゆえに、 認知バイアスを通じて誤読を増幅してしまうリスクも比例して大きい。 「ピボットを作るときは、 自分の認知も同時に監査する」という二重意識が、 中級者から上級者への分水嶺になる。

🏗 ピボットテーブル設計テンプレート 6 種(コピペ可)

最後に、 SSDSE-B-2026 で頻繁に使う 6 種類のピボットテンプレートを並べる。 これらは「最頻出パターンを覚えておくと現場で考える時間を節約できる」ためのリファレンス用途で、 引数の入れ替えのみで多くの分析依頼に対応できる。 すべて pandas API を前提とし、 そのままコピペして列名だけ書き換えれば動く形にしてある。

用途テンプレート出力イメージよくある追加処理
①地域別合計pd.pivot_table(df, index='地域', values='人口', aggfunc='sum')7 地域 × 1 指標棒グラフで降順表示
②都道府県別多指標pd.pivot_table(df, index='都道府県', values=['総人口','65歳以上人口','消費支出(二人以上の世帯)'], aggfunc='sum')47 県 × 3 指標.corr() でヒートマップ
③年度別推移pd.pivot_table(df, index='年度', columns='地域', values='人口', aggfunc='sum')17 年 × 7 地域折れ線図で 7 本表示
④代表値 4 種同時pd.pivot_table(df, index='地域', values='人口', aggfunc=['mean','median','std','count'])7 地域 × 4 統計量箱ひげ図で分布補完
⑤割合(行方向 normalize)pd.crosstab(df['地域'], df['サイズ区分'], normalize='index')7 地域 × N 区分(合計 1.0)100% 積み上げ棒グラフ
⑥カスタム集計関数pd.pivot_table(df, index='地域', values='人口', aggfunc=lambda x: x.quantile(0.9))7 地域 × 90 パーセンタイル分位点比較表に拡張

この 6 種を完全に手に馴染ませておけば、 SSDSE-B-2026 以外のオープンデータでも、 顧客の業務データでも、 同じ思考フローでピボットを組み立てられる。 重要なのは「テンプレートを暗記する」ことではなく、 「テンプレートの背後にある index・columns・values・aggfunc の選び方ロジック」を内在化することである。 テンプレートはあくまで思考の 足場 であり、 足場を組んだら自分の問いに合わせて自由に変形できる柔軟性こそが、 ピボット運用の到達点である。

🔄 ピボット × 機械学習:特徴量エンジニアリングとしての側面

ピボットテーブルは可視化と検定だけでなく、 機械学習の特徴量エンジニアリングにおいても核となる役割を果たす。 たとえば「顧客 × 商品カテゴリ × 月」の購入金額をピボットして wide 化すれば、 そのまま顧客クラスタリングの入力行列になる。 SSDSE-B-2026 を題材にしても、 「都道府県 × 産業 × 年度」の出荷額をピボットして wide 化すれば、 都道府県を 1 行とする多次元ベクトルが得られ、 k-means や階層クラスタリングで「経済構造が似ている県群」を抽出できる。

ピボットの形機械学習タスク行 = サンプル列 = 特徴量
都道府県 × 指標クラスタリング47 県複数指標
都道府県 × 年度時系列クラスタリング47 県17 年分の人口
都道府県 × 産業非負行列分解(NMF)47 県N 産業の出荷額
都道府県 × 年代別人口比率主成分分析(PCA)47 県年代別比率

機械学習の前処理におけるピボットの役割は「観測値の long → wide 変換」が中心で、 これは scikit-learn が要求する「行 = サンプル、 列 = 特徴量」という標準入力形式への変換そのものである。 つまり、 ピボットテーブルを使いこなすことは、 機械学習の前処理パイプラインを自在に組み立てる能力に直結する。 ピボット → 標準化 → モデル投入という流れを 1 ノートブック内で完結できるのが、 pandas + scikit-learn の組み合わせの最大の魅力である。

🗂 ピボットテーブルの保存・共有・バージョン管理

ピボットテーブルは作って終わりではなく、 「再現できる形で保存し、 チームと共有し、 変更を追跡する」までセットで運用する必要がある。 SSDSE-B-2026 のような公的データを使った分析は数ヶ月〜数年単位で継続することが多く、 当時のピボット引数や元データのバージョンを思い出せないと、 結論の妥当性そのものが揺らぐ。 ここでは保存・共有・バージョン管理の 3 軸でベストプラクティスを整理する。

推奨手段理由具体的な実装
保存CSV/Parquetテキスト or 列指向で長期保存に強いdf_pivot.to_csv('out/pivot_population.csv')
共有(表)Excel / Google スプレッドシート非エンジニアも読めるdf_pivot.to_excel('out/pivot.xlsx', sheet_name='地域別人口')
共有(コード)Jupyter Notebook引数・出力・可視化を 1 ファイルに同梱jupyter nbconvert pivot_analysis.ipynb --to html
バージョン管理Git + DVCコードと生データを別管理dvc add data/ssdse_b_2026.csv && git commit
注釈README.md と出典明記将来の自分・第三者が文脈を復元できる「出典:SSDSE-B-2026、 集計関数:sum、 欠損処理:NaN 保持」と書く

特に重要なのは「ピボットの出力 CSV を git にコミットせず、 ピボットを生成する スクリプト を git にコミットする」という原則である。 出力 CSV を直接管理してしまうと、 元データが更新されたときに「どの引数で再生成すれば同じ結果が得られるか」が失われる。 スクリプト経由なら、 元データを差し替えて再実行するだけで最新のピボットが得られ、 過去の引数履歴も git log に残る。 これが「再現可能な分析(Reproducible Research)」の中核思想であり、 SSDSE-B-2026 のように毎年データが更新される公的データには特に親和性が高い。

🧭 ピボットテーブルのパフォーマンス・チューニング指針

SSDSE-B-2026 は 47 行 × 数十列の小規模データのためピボットは瞬時に終わるが、 同じ手法を数百万行の業務データに適用するとメモリ不足や処理時間で躓くことがある。 ここでは pandas 上でピボットテーブルを高速・低メモリで動かすための実践的なチューニング指針を 6 点まとめる。 SSDSE-B-2026 でこの指針を実験的に確認しておくと、 後で大規模データに直面したとき即座に対応できる。

これら 6 つのチューニング指針を順に試せば、 47 行で動いていたピボットが 4700 万行のデータでもストレスなく動くようになる。 重要なのは「最初から複雑な最適化を施す」のではなく、 「まず小規模で動かして妥当性を確認し、 必要に応じて段階的に最適化する」という段階主義である。 SSDSE-B-2026 は段階主義の練習場として理想的で、 まず素直に書いて、 次に各指針を 1 つずつ試して効果を実測し、 体感として最適化の感覚を身につけるとよい。

🌐 ピボットテーブルが拓く「再現可能な分析文化」

ここまで見てきたように、 ピボットテーブルは単なる集計コマンドではなく、 データ分析全体を貫く「言語」「設計図」「コミュニケーション媒体」である。 ピボットを軸に据えると、 元データ取得 → 前処理 → 集計 → 可視化 → 統計検定 → 機械学習 → レポート提出という分析パイプラインの全工程が、 同じ index・columns・values・aggfunc という 4 つのキーワードで貫通される。 これは「データを語るための共通文法を持つ」ことに等しく、 チーム内コミュニケーションのコストを劇的に下げる効果がある。

SSDSE-B-2026 は、 この共通文法を身につけるための最高の教材である。 公的データであり改変・公開が自由で、 47 都道府県という直感的に把握できる規模で、 複数年度・複数指標を備える。 本記事の R347 視覚化深堀りを 1 通り写経し、 各表を自分のノートで再現し、 可視化を 1 枚ずつ描き、 ピボット引数を 1 つずつ変えて違いを確認する。 これを 1〜2 週間続ければ、 SSDSE-B-2026 を題材にピボットを「設計言語」として体得した、 と胸を張って言える状態に到達する。 そこから先は、 別のデータセット・別のドメイン・別のチームに同じ思考を転用するだけで、 学習投資が長く回収できる。

📌 ピボットを通じて見える「データ分析の三層構造」

ピボットを毎日触っていると、 データ分析には三層構造があることに気付く。 第一層は「個別の観測値」であり、 47 都道府県 × 17 年度 × N 指標といった生の数値である。 第二層は「集計値」であり、 ピボットテーブルがまさにこの層を可視化する道具である。 第三層は「集計値から導かれる解釈・仮説・意思決定」であり、 ピボットの数値を読みながら分析者の頭の中で形成される。 ピボットテーブルは第一層と第三層を橋渡しする中継地点であり、 この三層構造を意識的に往復することが、 データ分析の本質的な営みである。 SSDSE-B-2026 で第二層をたっぷり練習することで、 第一層への解像度と第三層への抽象化能力が同時に鍛えられる。

📖 まとめ:ピボットと可視化は「双子」である

ピボットテーブルは表形式で結論を「凝縮」する強力な装置だが、 凝縮には常に「情報の損失」が伴う。 損失した情報を回収する手段が、 散布図・ヒストグラム・箱ひげ図・ヒートマップ・折れ線図といった可視化群である。 ピボットの行・列・値・集計関数を 1 つ変更したら、 必ず対応する可視化も 1 図描き直す。 この往復運動こそが「ピボットテーブルを使いこなす」ことの中身であり、 BI ダッシュボードに並ぶ複数の図表は、 すべて 1 つのピボットの異なる側面を可視化している、 と理解すると一気に視界が開ける。 SSDSE-B-2026 を題材に上記 5 視覚化を最低 1 巡こなしておくと、 実務で初見のデータに遭遇したときも「まずピボット、 次に箱ひげ、 続いてヒートマップ」という再現可能な手順を即座に立ち上げられる。

本章で示した「視覚化と数表を双子として扱う」習慣は、 ピボットテーブルに限らず、 群比較・相関分析・時系列分析・クラスタリング・回帰分析など、 あらゆる分析手法で通用する普遍的な作法である。 数値だけを見て結論を急がない、 図だけを見て根拠を曖昧にしない、 数値と図を常にペアで提示する、 という三原則を守るだけで、 分析の説得力は確実に底上げされる。 ピボットテーブルはその訓練のための最も身近な題材であり、 SSDSE-B-2026 はその訓練のための最も入手しやすい教材である。 この組み合わせを徹底的に活用し、 ピボットを「読み・書き・話せる言語」として体得していただきたい。 ピボットテーブルの上達は、 すなわちデータ分析全体の上達である。 SSDSE-B-2026 という共通の練習場を通じて、 数表と可視化を双子として扱う作法を、 ぜひ自分の身体に染み込ませて欲しい。

🧮 数式に値を入れて手で計算する: ピボットテーブルの集計

合成データで店舗×月の売上ピボットを計算する。

Step 1: 元データ

店舗売上
A1月100
A2月120
B1月80
B2月90

Step 2: ピボット (店舗×月)

1月 2月 合計 A 100 120 220 B 80 90 170 合計 180 210 390

🐍 Python で再現

1
2
3
4
5
6
7
8
import pandas as pd
df = pd.DataFrame({
  '店舗':['A','A','B','B'],
  '月':['1月','2月','1月','2月'],
  '売上':[100, 120, 80, 90]
})
pv = pd.pivot_table(df, values='売上', index='店舗', columns='月', aggfunc='sum', margins=True)
print(pv)

📤 実行結果

月 1月 2月 All 店舗 A 100 120 220 B 80 90 170 All 180 210 390

💬 手計算 (Step 2) と Python 出力が完全一致。

🎮 触って理解する

下の個票データは SSDSE-B-2026 実測値(東京都・神奈川県・大阪府・兵庫県・福岡県・沖縄県 × 2021〜2023 年 = 18 行。総人口 A1101、合計特殊出生率 A4103)。「行」「列」「値」「集計関数」を切り替えると、ピボット表と色マップ(SVG)がその場で再計算される。ピボット表または色マップのセルをタップすると、そのセルが個票のどの行から集計されたかが左の表でハイライトされる。

📋 個票データ(long 形式・18 行)
📊 ピボット結果(
🎨 色マップ(同じピボットを色の濃淡で)
👆 ピボット表か色マップのセルをタップすると、集計元の個票行が分かります。

🎨 直感:ピボットは「2 本の軸で切って、束ねて、潰す」操作

個票 1 行 1 行は「誰が・いつ・いくら」という記録にすぎない。ピボットテーブルは、①カテゴリ変数 2 つを行軸・列軸として空間を格子状に切り、②各セルに落ちる個票行を束ね、③集計関数で 1 個の数値に潰す——という 3 段階の操作である。上のデモで「行列入替」を押すと表が転置されるが、セルの中身(束ねられる個票行の集合)は全く同じであることを確認してほしい。行と列の選択は情報を変えず「どちらの比較を横に並べて読みたいか」だけを変えている。

⚠️ 触って気づく落とし穴

🚀 発展:多段ピボット・pandas・BI ツール

🐍 Python 実装

① 基本的なピボットテーブル:地方 × 指標

🎯 このコードでやること:SSDSE-B-2026 の 2023 年データから、 47 都道府県を 8 地方ブロックに集計してピボット表にする。

📥 入力データ:SSDSE-B-2026.csv (47 都道府県 × 2023 年)、 地方マッピング辞書

都道府県 総人口 65歳以上人口 消費支出(二人以上の世帯) 地方 北海道 5092000 1681000 296888 北海道 青森県 1184000 417000 263371 東北 ... ... ... ... ... 沖縄県 1468000 350000 251222 九州沖縄
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import pandas as pd

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1)
d23 = df[df['年度']==2023].copy()

# 地方ブロックを付与
d23['地方'] = d23['都道府県'].map({'北海道':'北海道', '青森県':'東北', '宮城県':'東北',
    '東京都':'関東', '愛知県':'中部', '大阪府':'近畿', '広島県':'中国',
    '香川県':'四国', '福岡県':'九州沖縄', '沖縄県':'九州沖縄'})  # …他県も
# 残り 37 県も同じ 8 区分に割り当てる(全 47 県を埋めないと NaN になり集計から落ちる)
_rest = {'岩手県':'東北','秋田県':'東北','山形県':'東北','福島県':'東北','茨城県':'関東','栃木県':'関東','群馬県':'関東','埼玉県':'関東','千葉県':'関東','神奈川県':'関東','新潟県':'中部','富山県':'中部','石川県':'中部','福井県':'中部','山梨県':'中部','長野県':'中部','岐阜県':'中部','静岡県':'中部','三重県':'近畿','滋賀県':'近畿','京都府':'近畿','兵庫県':'近畿','奈良県':'近畿','和歌山県':'近畿','鳥取県':'中国','島根県':'中国','岡山県':'中国','山口県':'中国','徳島県':'四国','愛媛県':'四国','高知県':'四国','佐賀県':'九州沖縄','長崎県':'九州沖縄','熊本県':'九州沖縄','大分県':'九州沖縄','宮崎県':'九州沖縄','鹿児島県':'九州沖縄'}
d23['地方'] = d23['地方'].fillna(d23['都道府県'].map(_rest))

pv = d23.pivot_table(
    index='地方',
    values=['総人口', '65歳以上人口', '消費支出(二人以上の世帯)'],
    aggfunc='sum'
)
print(pv)

📤 実行すると次の出力が得られる

65歳以上人口 消費支出(二人以上の世帯) 総人口 地方 中国 2263000 1460752 7070000 中部 6161000 2745302 20749000 九州沖縄 4291000 2233623 14029000 北海道 1681000 296888 5092000 四国 1230000 1106113 3578000 東北 2790000 1769712 8318000 近畿 6423000 2077281 21990000 関東 11390000 2215562 43527000

💬 結果の読み方:8 地方ブロック × 3 指標 = 24 セルの集計が 1 行のコードで完成。 関東が圧倒的に大きいが、 1 県あたり (関東 7 県) で割ると面白い構造が見えるかも。

② 都道府県 × 年度のピボット (時系列分析の準備)

🎯 このコードでやること:SSDSE-B-2026 の 564 行を「行=都道府県、 列=年度」のピボット表に変換し、 各県の時系列を一覧化する。

📥 入力データ:SSDSE-B-2026 全 564 行 (47 県 × 12 年)

1
2
3
4
5
6
7
import pandas as pd

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1)

# 行=都道府県、 列=年度、 値=総人口
pv = df.pivot_table(index='都道府県', columns='年度', values='総人口')
print(pv.loc[['東京都', '北海道', '沖縄県']])

📤 実行すると次の出力が得られる (一部抜粋):

年度 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 都道府県 東京都 13234000 13307000 13399000 13515271 13646000 13768000 13887000 14007000 14047594 14010000 14038000 14086000 北海道 5465000 5438000 5410000 5381733 5355000 5325000 5293000 5259000 5224614 5183000 5140000 5092000 沖縄県 1411000 1419000 1426000 1433566 1442000 1448000 1454000 1462000 1467480 1468000 1468000 1468000

💬 結果の読み方:東京都は微増 (1,326 万→1,409 万)、 北海道は大幅減 (546 万→509 万, -37 万人)、 沖縄県は緩やかに増加。 ピボット表 1 つで 47 県 × 12 年 = 564 個の数値関係が把握可能。

③ aggfunc を変えて多角的に集計

🎯 このコードでやること:同じピボット構造で aggfunc を変え、 sum, mean, count, max, min, std を一度に出力する。 複数集計を 1 つのピボットに統合する典型例。

📥 入力データ:①の d23 (47 都道府県)

1
2
3
4
5
6
7
# 年平均気温を地方別に複数集計
pv = d23.pivot_table(
    index='地方',
    values='年平均気温',
    aggfunc=['mean', 'min', 'max', 'count']
)
print(pv.round(2))

📤 実行すると次の出力が得られる

mean min max count 年平均気温 年平均気温 地方 中国 16.80 16.50 17.50 5 中部 16.38 13.60 18.20 9 九州沖縄 19.04 17.60 23.80 8 北海道 11.00 11.00 11.00 1 四国 17.73 17.60 17.90 4 東北 13.78 12.50 15.20 6 近畿 17.36 16.30 18.00 7 関東 17.13 16.00 18.10 7

💬 結果の読み方:「九州沖縄」が平均 19.0℃ で最高だが、 沖縄 23.8℃ を含むことでレンジ 6.2℃ と最も広い。 count 列で「各地方の県数」も自動表示。 1 つのピボット呼び出しで 4 種類の集計を同時に取得できるのが pandas の強み。

④ margins=True で行・列合計を追加

🎯 このコードでやること:地方 × 年度の総人口ピボットで margins=True を使い、 行合計 (各地方の 12 年合計)・列合計 (各年の全国合計)・全体合計を追加。

📥 入力データ:SSDSE-B-2026 全 564 行 + 地方マッピング

1
2
3
4
5
6
7
pv = d23.pivot_table(
    index='地方',
    values='総人口',
    aggfunc='sum',
    margins=True, margins_name='全国'
)
print(pv)

📤 実行すると次の出力が得られる

総人口 地方 中国 7070000 中部 20749000 九州沖縄 14029000 北海道 5092000 四国 3578000 東北 8318000 近畿 21990000 関東 43527000 全国 124353000

💬 結果の読み方:margins=True で「全国」行が自動追加され、 全国合計 1 億 2435 万人が一目で分かる。 各地方の構成比 (例:関東 35%) も計算しやすくなる。 Excel のピボットで「全合計を表示」をチェックするのと同じ。

⚠️ よくある落とし穴

⚠️ 重複行を無視して平均が取られる
SSDSE-B-2026 のように (都道府県, 年度) 組み合わせが一意なら問題ないが、 同じキーが複数あると aggfunc='mean' がデフォルトで適用される。 「sum したつもりが mean だった」事故を防ぐため、 必ず aggfunc を明示する。
⚠️ 欠損セルの扱い
ピボット後の NaN セルは「該当組み合わせなし」を意味する。 SSDSE-B-2026 は 47×12=564 行のフル組み合わせなので欠損は出ないが、 一部年度のみのデータでは NaN が発生。 fill_value=0 で埋めるか、 残して欠損を可視化するかは目的次第。
⚠️ 巨大な横持ちテーブル化
SSDSE-B-2026 の 112 カラム全てをピボットすると列数が爆発して読めなくなる。 「行=都道府県、 列=指標 (最大 5 つくらい)」程度に絞る。 多数の指標を一覧したい場合は melt で縦持ちに戻すか、 ヒートマップで可視化。
⚠️ aggfunc を指定しない (文字列連結事故)
数値以外 (例: 都道府県名) で aggfunc='sum' を使うと文字列連結される (「東京都大阪府...」のように)。 数値カラムに限定するか、 aggfunc='first''count' を使う。
⚠️ ピボット結果がマルチインデックスで扱いにくい
複数の values を指定したり aggfunc にリストを渡すと、 結果は MultiIndex DataFrame になる。 列名が「('mean', '年平均気温')」のようにタプル化されて扱いにくい。 .reset_index() で平坦化、 または列名を list(map(lambda x: '_'.join(x).strip('_'), pv.columns)) で結合。
⚠️ margins=True の合計セルを再集計してしまう
margins で追加した「全国」行を、 別の処理 (平均など) で間違って混ぜると重複計上になる。 ピボット表示用のラベルとして使い、 計算には含めないのが原則。
⚠️ pivot と pivot_table を混同
df.pivot() は (index, columns) の組み合わせがユニークでないと エラーになる単純版。 df.pivot_table() は重複時に aggfunc で集約してくれる強化版。 SSDSE-B-2026 のような複雑データでは pivot_table を使うのが安全。
⚠️ メモリ消費に注意
100 万行の DataFrame を都道府県 (47) × 業種 (1000) × 年月 (60) でピボットすると 47*1000*60=282 万セルに膨らむ。 SSDSE-B-2026 は 564 行なので余裕だが、 大規模データでは事前に絞り込む。

📊 縦持ち (long) と横持ち (wide) の比較

SSDSE-B-2026 は 縦持ち形式:1 行 = 1 (都道府県, 年度) 組み合わせ、 各カラムが指標。 ピボットで横持ちに変換すると分析しやすくなる。

観点縦持ち (long)横持ち (wide)
SSDSE-B-2026 の形○ (564 行 × 112 列)
機械学習入力そのまま使える展開すると特徴量爆発
時系列可視化groupby+plot で OK直接 plot 可
人間が読む情報密度低い表として最適
SQL/データベース正規化済み (推奨)非正規化 (集計後)
変換 APImelt()pivot_table()

⑤ 横持ち ↔ 縦持ち変換

🎯 このコードでやること:SSDSE-B-2026 のピボット結果を melt で縦持ちに戻す。 機械学習やデータベース格納時に必要な前処理。

📥 入力データ:②で作った都道府県 × 年度 ピボット (47 行 × 12 列)

1
2
3
4
5
6
7
# pivot 後の wide DataFrame
wide = df.pivot_table(index='都道府県', columns='年度', values='総人口')

# wide → long 変換 (melt 同等)
long = wide.reset_index().melt(id_vars='都道府県', value_name='総人口')
print(long.head())
print(f'行数: {len(long)}')

📤 実行すると次の出力が得られる

都道府県 年度 総人口 0 三重県 2012 1841000.0 1 京都府 2012 2628000.0 2 佐賀県 2012 845000.0 3 兵庫県 2012 5575000.0 4 北海道 2012 5465000.0 行数: 564

💬 結果の読み方:47 行 × 12 列の wide を melt で 47×12=564 行の long に戻した。 元の SSDSE-B-2026 と同じ形。 「pivot → 集計 → melt → 別の集計」のように行き来する場面が実務でよくある。

🗺 ピボットを含むデータ変形ファミリーマップ

                ┌─── データ変形 ────┐
                │                    │
            縦持ち (long)         横持ち (wide)
                │                    │
                ├──── pivot_table ───┤
                ├──── pivot ─────────┤
                ├──── crosstab ──────┤  (カウント特化)
                ├──── groupby+unstack┤
                │                    │
                ├──── melt ──────────┤ (逆変換: wide→long)
                └──── stack/unstack ─┘ (MultiIndex 変形)

   pivot_table の引数
   ├── index    : 行に置くキー
   ├── columns  : 列に置くキー (省略可)
   ├── values   : セルの値 (省略すると全数値カラム)
   ├── aggfunc  : 集約関数 (省略=mean)
   ├── fill_value : NaN セルの埋め値
   ├── margins  : 行/列合計を追加
   └── dropna   : 全 NaN 列の扱い
  

📌 ピボットテーブルを覚える 7 つのポイント

  1. 縦持ち → 横持ち変換が本質。 SSDSE-B-2026 の 564 行を 47 行 × 12 列に。
  2. 4 つの引数を覚える:index, columns, values, aggfunc。
  3. aggfunc を必ず指定。 デフォルトの mean に頼ると思わぬ事故。
  4. margins=True で合計行・列を自動追加。 Excel ピボットと同じ。
  5. MultiIndex で階層的集計が可能。 pv.loc['関東'] で部分抽出。
  6. crosstab はカウント特化版。 カテゴリ × カテゴリの集計に便利。
  7. melt で逆変換。 wide → long に戻すのは機械学習・DB 格納時に必須。

本ページの SSDSE-B-2026 実例まとめ:47 都道府県を 8 地方ブロックにピボット集計、 12 年分の時系列を「都道府県 × 年度」表に、 aggfunc=['mean','min','max','count'] で多角集計、 margins で全国合計を追加、 MultiIndex で階層構造、 crosstab で「地方 × 気温区分」のカウント表 (10-15℃帯 8 県、 15-18℃帯 24 県、 18℃以上 15 県)。 これら全てが pivot_table の 1〜2 行コードで実現できる。

📋 SSDSE-B-2026 をピボット分析向けに拡張する

SSDSE-B-2026 そのままでは「カテゴリ列」が「都道府県」と「年度」しかない。 ピボット分析の幅を広げるため、 派生カテゴリを追加するのがコツ。

追加すべき派生カテゴリ

派生カテゴリ作り方用途
地方ブロック (8 区分)都道府県 → 北海道/東北/関東/中部/近畿/中国/四国/九州沖縄地域別集計
人口規模 (3 区分)総人口 > 5M = 大, 1-5M = 中, <1M = 小県規模別分析
気候帯 (3 区分)年平均気温 >18=暖, 15-18=温, <15=寒気候別比較
高齢化区分 (3 区分)65 歳以上人口 / 総人口 > 0.30 = 高齢化深刻人口構造別
年代区分 (3 区分)2012-2015 = 前期, 2016-2019 = 中期, 2020-2023 = 後期 (コロナ含む)時代区分別
三大都市圏東京圏/名古屋圏/大阪圏/地方都市圏分析

⑧ 複数派生カテゴリを使った 3 次元ピボット

🎯 このコードでやること:SSDSE-B-2026 に「年代区分」と「地方」の 2 派生カテゴリを追加し、 「地方 × 年代」のクロス集計を行う。 12 年の変動を 3 期に集約することで、 トレンドが見やすくなる。

📥 入力データ:SSDSE-B-2026 全 564 行 + 地方 + 年代

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# ── この抜粋で使うデータを用意します(年度をまたぐので全 12 年度)──
import pandas as pd

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1)
df['高齢化率'] = df['65歳以上人口'] / df['総人口'] * 100
# 「地方」は SSDSE に無い列なので、都道府県名から 8 地方区分を作る
_BLOCKS = {
    '北海道': ['北海道'],
    '東北': ['青森県', '岩手県', '宮城県', '秋田県', '山形県', '福島県'],
    '関東': ['茨城県', '栃木県', '群馬県', '埼玉県', '千葉県', '東京都', '神奈川県'],
    '中部': ['新潟県', '富山県', '石川県', '福井県', '山梨県', '長野県',
             '岐阜県', '静岡県', '愛知県'],
    '近畿': ['三重県', '滋賀県', '京都府', '大阪府', '兵庫県', '奈良県', '和歌山県'],
    '中国': ['鳥取県', '島根県', '岡山県', '広島県', '山口県'],
    '四国': ['徳島県', '香川県', '愛媛県', '高知県'],
    '九州・沖縄': ['福岡県', '佐賀県', '長崎県', '熊本県', '大分県', '宮崎県',
                   '鹿児島県', '沖縄県'],
}
_R = {p: g for g, ps in _BLOCKS.items() for p in ps}
df['地方'] = df['都道府県'].map(_R)
df['地域'] = df['地方']

# 年代区分を追加
df['年代'] = pd.cut(df['年度'], bins=[2011,2015,2019,2023],
                     labels=['前期(2012-15)','中期(2016-19)','後期(2020-23)'])

# 地方 × 年代の出生率平均
pv = df.pivot_table(index='地方', columns='年代',
                    values='合計特殊出生率', aggfunc='mean')
print(pv.round(3))

📤 実行すると次の出力が得られる

年代 前期(2012-15) 中期(2016-19) 後期(2020-23) 地方 中国 1.584 1.596 1.472 中部 1.494 1.519 1.391 九州沖縄 1.650 1.670 1.548 北海道 1.280 1.272 1.148 四国 1.509 1.535 1.411 東北 1.421 1.415 1.242 近畿 1.418 1.424 1.323 関東 1.352 1.361 1.218

💬 結果の読み方:全 8 地方で「前期 > 中期 > 後期」と一貫して出生率が低下。 九州沖縄が常に最高 (1.69 → 1.53)、 北海道が常に最低 (1.26 → 1.15)。 年代を 3 期に集約することで「コロナ後の急減」が明確に見える。 12 年を月単位で見るより、 3 期集約が政策議論には適している。

🎯 ⑨ ピボット結果を ASCII ヒートマップで可視化

🎯 このコードでやること:12 年×8 地方の出生率ピボットを ASCII 表現 (●○) でヒートマップ風に視覚化する。 matplotlib なしでもパターンが見える。

📥 入力データ:地方×年度の出生率ピボット表 (8 行 × 12 列)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# ── この抜粋で使うデータを用意します(年度をまたぐので全 12 年度)──
import pandas as pd

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1)
df['高齢化率'] = df['65歳以上人口'] / df['総人口'] * 100
# 「地方」は SSDSE に無い列なので、都道府県名から 8 地方区分を作る
_BLOCKS = {
    '北海道': ['北海道'],
    '東北': ['青森県', '岩手県', '宮城県', '秋田県', '山形県', '福島県'],
    '関東': ['茨城県', '栃木県', '群馬県', '埼玉県', '千葉県', '東京都', '神奈川県'],
    '中部': ['新潟県', '富山県', '石川県', '福井県', '山梨県', '長野県',
             '岐阜県', '静岡県', '愛知県'],
    '近畿': ['三重県', '滋賀県', '京都府', '大阪府', '兵庫県', '奈良県', '和歌山県'],
    '中国': ['鳥取県', '島根県', '岡山県', '広島県', '山口県'],
    '四国': ['徳島県', '香川県', '愛媛県', '高知県'],
    '九州・沖縄': ['福岡県', '佐賀県', '長崎県', '熊本県', '大分県', '宮崎県',
                   '鹿児島県', '沖縄県'],
}
_R = {p: g for g, ps in _BLOCKS.items() for p in ps}
df['地方'] = df['都道府県'].map(_R)
df['地域'] = df['地方']

pv = df.pivot_table(index='地方', columns='年度',
                    values='合計特殊出生率', aggfunc='mean')

def to_dot(x):  # 値 → ●/○ への変換
    if x >= 1.5: return '●●'
    elif x >= 1.3: return '● '
    else: return '○ '
print(pv.map(to_dot))

📤 実行すると次の出力が得られる

年度 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 地方 中国 ●● ●● ●● ●● ●● ●● ●● ●● ●● ● ● ● 中部 ● ● ● ●● ●● ●● ●● ● ● ● ● ● 九州沖縄 ●● ●● ●● ●● ●● ●● ●● ●● ●● ●● ●● ● 北海道 ○ ○ ○ ● ○ ○ ○ ○ ○ ○ ○ ○ 四国 ● ●● ● ●● ●● ●● ●● ● ● ● ● ● 東北 ● ● ● ● ● ● ● ● ● ○ ○ ○ 近畿 ● ● ● ● ● ● ● ● ● ● ● ○ 関東 ● ● ● ● ● ● ● ● ○ ○ ○ ○

💬 結果の読み方:●● は出生率 1.5 以上、 ● は 1.3-1.5、 ○ は 1.3 未満。 「九州沖縄」が 12 年通じて ●● を維持、 「北海道」は全て ○、 「中国・四国」が 2021 頃から ●● から ● に転落、 「関東・東北」が 2020 以降 ○ に。 数値表より一目で時空間パターンが把握できる。 pivot_table と単純な map で実現可能。

🎓 ピボット vs SQL GROUP BY の対応関係

pandas の pivot_table は SQL の GROUP BY ... PIVOT に相当。 主要 DB エンジンとの対応:

操作pandasSQL 一般Excel
合計集計pivot_table(aggfunc='sum')SUM() GROUP BYピボット (合計)
平均集計aggfunc='mean'AVG()ピボット (平均)
カウントaggfunc='count' または crosstabCOUNT()ピボット (個数)
縦→横変換columns=...PIVOT 句 (Oracle/T-SQL)行/列フィールド設定
横→縦変換meltUNPIVOT逆ピボット
合計行追加margins=TrueWITH ROLLUP総計表示 ON

SSDSE-B-2026 を SQL に格納すれば、 同じピボット集計を SELECT 地方, SUM(CASE WHEN 年度=2023 THEN 総人口 END) FROM ... GROUP BY 地方 のように書ける。 ただし pandas のほうが圧倒的に簡潔。

❓ よくある質問

Q1. pivot と pivot_table の違いは何ですか?

A. df.pivot() は (index, columns) の組み合わせが ユニークでないとエラー。 df.pivot_table() は重複時に aggfunc で集約してくれる。 SSDSE-B-2026 のように都道府県 × 年度が一意なデータでは pivot でも OK だが、 pivot_table のほうが汎用なので常にこちらを使うのが安全。

Q2. groupby と pivot_table はどちらを使うべき?

A. 結果の形が違うだけで本質は同じ。 df.groupby(['地方','年度'])['総人口'].sum().unstack('年度')df.pivot_table(index='地方', columns='年度', values='総人口', aggfunc='sum') と完全に等価。 「行 × 列の集計表が欲しい」なら pivot_table が直感的、 「長いままで処理を続けたい」なら groupby。

Q3. ピボットで NaN が出るのはなぜ? どう対処する?

A. (index, columns) の組み合わせにデータが存在しない場合 NaN になる。 SSDSE-B-2026 の 47×12 はフル組み合わせなので発生しないが、 一部年度しかない調査だと NaN が出る。 対処法:(1) fill_value=0 で 0 埋め、 (2) NaN のまま残して欠損を可視化、 (3) .dropna() で除外。 目的に応じて選ぶ。

Q4. 複数の aggfunc を同時に指定するとどうなる?

A. aggfunc=['mean','sum'] のようにリストで渡すと、 結果は MultiIndex 列となり ('mean', '総人口'), ('sum', '総人口') の 2 階層列が作られる。 dict 形式 aggfunc={'総人口':'sum', '気温':'mean'} で「カラムごとに違う集計」も可能。 SSDSE-B-2026 のように多指標データでは dict 形式が便利。

Q5. ピボット結果を CSV や Excel に書き出すには?

A. pv.to_csv('output.csv') または pv.to_excel('output.xlsx') で OK。 ただし index が MultiIndex の場合、 Excel で読むときに見づらいので pv.reset_index().to_excel(...) で平坦化推奨。 SSDSE-B-2026 を地方×年度ピボットして Excel に出力すれば、 そのままレポートに貼れる形式。

Q6. ピボットテーブルの計算量はどれくらい?

A. SSDSE-B-2026 の 564 行のような小規模なら一瞬。 大規模 (100 万行以上) でも pandas は O(n log n) 程度で処理。 ボトルネックは「ピボット後のメモリ」で、 unique 値が多い列を columns に置くと爆発する。 都道府県 (47) は OK だが、 「日付 (5000)」を columns にするのは要注意。

Q7. Excel と pandas のピボット、 結果は完全に一致しますか?

A. 概ね一致しますが、 (1) Excel は文字列でも勝手に sum を試みる、 (2) NaN/空セルの扱いが微妙、 (3) Excel ピボットは集計関数の選択肢が限られる (中央値が標準にない) — などの違いあり。 SSDSE-B-2026 のような数値データの基本集計なら、 両者で同じ結果が得られる。

📊 練習問題

  1. 基本問題:SSDSE-B-2026 を 8 地方ブロックに分けて、 2023 年の年平均気温の平均を求めなさい。
    解答を見る
    中国 16.80, 中部 16.38, 九州沖縄 19.04, 北海道 11.00, 四国 17.73, 東北 13.78, 近畿 17.36, 関東 17.13 (℃)。 沖縄 23.8℃ の影響で「九州沖縄」が最高、 北海道が最低。
  2. 応用問題:SSDSE-B-2026 で、 2023 年の都道府県別「65 歳以上人口比率 = 65歳以上人口 / 総人口」を計算し、 地方別の平均を求めなさい。
    解答を見る
    d23['高齢化率'] = d23['65歳以上人口']/d23['総人口'] を計算し、 d23.pivot_table(index='地方', values='高齢化率', aggfunc='mean')。 結果は概ね北海道 0.330, 東北 0.336, 四国 0.34 と地方が高く、 関東 0.262, 近畿 0.30 と都市部が低い。
  3. 変換問題:⑧ で作った「地方 × 年代」の出生率ピボット (8 行 × 3 列) を、 縦持ち long 形式に melt しなさい。 結果は何行になりますか?
    解答を見る
    8 × 3 = 24 行の long フォーマット。 列名は ['地方', '年代', '値']。 wide ↔ long は情報量が変わらないので、 セル数は常に行 × 列に一致する。
  4. 応用問題:SSDSE-B-2026 の 564 行から「都道府県 × 年度」ピボット (47 × 12) を作り、 各都道府県の 12 年間の人口減少率 ((2023値 - 2012値) / 2012値 × 100) を計算しなさい。 最も人口減少率が大きい県は?
    解答を見る
    秋田県が約 -14% で最大の減少率。 次いで青森・高知・山形・岩手など東北・四国の地方県が続く。 一方、 東京都はほぼ横ばい〜微増、 沖縄県は微増。 ピボット表の差分計算で県別構造変化が一目瞭然になる。
  5. 応用問題:SSDSE-B-2026 の 47 都道府県を「人口規模 (大=5M超, 中=1-5M, 小=1M未満)」と「気候帯」の 2 軸で crosstab。 該当県数を 3×3 のクロス表で示しなさい。
    解答を見る
    概ね 「中規模 × 15-18℃」帯に最も集中 (15 県程度)、 大規模 (東京・大阪・神奈川・愛知・埼玉・千葉) は全て温暖以上。 小規模 (高知・島根・鳥取・徳島・福井等) は気候帯が分散。 crosstab(d23['人口規模'], d23['気候帯'], margins=True) で簡単に作成可。

📋 完全実例:47 都道府県 × 12 年度の総人口ピボット

SSDSE-B-2026 の df.pivot_table(index='都道府県', columns='年度', values='総人口') の完全結果 (47 行 × 12 列 = 564 セル)。 12 年間の変化が一目で分かる。

都道府県2012201420162018202020222023変化率
北海道5,4655,4105,3555,2935,2255,1405,092-6.8%
青森県1,3391,3211,2961,2611,2381,2051,184-11.6%
秋田県1,0631,0371,008980960930914-14.0%
岩手県1,2951,2791,2551,2261,2101,1821,163-10.2%
宮城県2,3262,3352,3252,3162,3022,2802,264-2.7%
山形県1,1601,1401,1161,0901,0681,0411,026-11.6%
福島県1,9621,9141,9011,8641,8331,7901,767-9.9%
東京都13,26513,35713,62413,82214,04814,03814,086+6.2%
神奈川県9,0679,1099,1599,1779,2379,2329,229+1.8%
埼玉県7,2127,2397,2897,3307,3447,3377,331+1.6%
千葉県6,2256,2386,2516,2726,2786,2666,324+1.6%
愛知県7,4207,4637,5077,5377,5427,4957,477+0.8%
大阪府8,8558,8308,8338,8138,8388,7828,765-1.0%
福井県793786782774767753744-6.2%
沖縄県1,4091,4211,4391,4481,4671,4681,465+4.0%

観察 (千人単位):(1) 三大都市圏 (東京・神奈川・埼玉・千葉・愛知) と沖縄は 増加、 (2) 東北 (青森・秋田・山形・福島) は 10% 超の減少、 (3) 秋田が -14.0% で最大の減少率。 ピボット表 1 つで 47 県 × 12 年 = 564 セルの構造変化が捉えられる。 これがピボットテーブルの威力。

🛠 ⑩ カスタム集計関数とラムダ式

🎯 このコードでやること:標準集計関数 (sum, mean...) で物足りない場合、 カスタム関数を aggfunc に渡せる。 SSDSE-B-2026 で「最大値と最小値の差 (range)」を地方別に集計。

📥 入力データ:2023 年 47 都道府県データ + 地方

1
2
3
4
5
6
# カスタム関数: 最大値 - 最小値 (range)
pv = d23.pivot_table(
    index='地方',
    values='総人口',
    aggfunc=lambda x: x.max() - x.min()
)
print(pv)

📤 実行すると次の出力が得られる

総人口 地方 中国 2201000 中部 6733000 九州沖縄 4308000 北海道 0 四国 625000 東北 1350000 近畿 7871000 関東 12189000 (内訳: 中国=広島−鳥取, 中部=愛知−福井, 九州沖縄=福岡−佐賀, 四国=愛媛−高知, 東北=宮城−秋田, 近畿=大阪−和歌山, 関東=東京−栃木)

💬 結果の読み方:関東の県内格差が最大 (1,218 万人, 東京 vs 群馬)、 北海道は 1 県なので差 0。 ラムダ式で「pandas が標準で持たない集計」も自由自在。 たとえば「IQR」「90%タイル」「指定値以上の比率」も同じ書き方で実現可能。

pivot table 行×列クロス集計 aggfunc 集計関数 Excel・pandas 連携 groupby との対比 margins・小計 wide-long 変換

🔗 隣接手法への橋渡し

ピボットテーブルは行・列にカテゴリ、 セルに集計値を配置する多次元クロス集計で、 Excel・pandas・BI ツールの標準機能。

SSDSE-B-2026 を用いた演習では、 「ピボットテーブル」 を中核に据えて上記の上流・並列・下流の手法を実データで連結する経験を積むと、 単独の手法暗記より実務的応用力が身につく。

🌳 手法選択フロー

「ピボットテーブル」を実際に使うとき、 何をどう選ぶかを順に判断する。 上から順に答えていくと、 使うべき手法と評価の仕方が決まる。

  1. 何を行、 何を列、 何を値にするか
    比較したい軸を列に、 並べたい軸を行に置く。 SSDSE-B-2026 なら行=都道府県、 列=年度、 値=総人口で 47×12 の表になる。
  2. 集約方法は何か
    合計・平均・件数・最大で結論が変わる。 人口のような量は合計でよいが、 比率や率は合計してはいけない。 率を集計するなら、 分子と分母をそれぞれ合計してから割る。
  3. 欠測をどう扱うか
    欠測セルを 0 と表示すると「値が 0」と読まれる。 空欄のままにするか、 「—」と明示する。 平均を取るときは、 欠測を除くのか 0 とみなすのかで結果が変わる。
  4. この先の処理は人が読むのか、 機械が読むのか
    人が読むならピボット(横持ち)が見やすい。 再集計や可視化に渡すなら整然データ(縦持ち)に戻す。 pivot_tablemelt は往復できる。

ピボットは「見せ方」の変換であって、 集計方法を誤ると元データが正しくても結論が変わる。 率を平均するときは特に注意。

🧭 深掘り:直感・落とし穴・発展(追記)

🎨 直感:ピボットは「縦持ちの束を、行×列の格子で潰す」

縦持ち(long)の 1 行は「誰の・いつの・どの指標か」という属性列と、 たった 1 個の値からなる素の記録にすぎない。 ピボットテーブルは、 この束を 行キー・列キー という 2 本の軸で格子状に仕切り、 各セルに落ちる複数行を 集計関数で 1 個の代表値に潰す。 GUI(Excel の行/列/値エリアへのドラッグ)でもコード(pivot_table(index, columns, values, aggfunc))でも、 やっていることは「多次元の集約 → 要約 → 可視化」という同一の流れである。 ピボットの出力そのものが ヒートマップ の入力行列になり、 集計 の考え方が土台になる。 「要約(数表)」と「可視化(色・図)」は地続きだと捉えるとよい。

⚠️ 落とし穴:集計関数の選択だけで「同じデータが別の物語」になる

下表は SSDSE-B-2026(cp932, skiprows=[1])の 2023 年・総人口 A1101 を 8 地方でピボットし、 集計関数だけを sum / mean / median に切り替えた実測結果である。 index・columns・values は完全に同一で、 変えたのは aggfunc 一つだけである点に注目してほしい。

2023 年 総人口 A1101(index=地方、 values=A1101、 aggfunc を切替) 地方 sum(合計) mean(平均) median(中央値) その地方の最大県 北海道 5,092,000 5,092,000 5,092,000 (1 県のみ) 東北 8,318,000 1,386,333 1,173,500 宮城 2,264,000 関東 43,527,000 6,218,143 6,257,000 東京 14,086,000 中部 20,749,000 2,305,444 1,931,000 愛知 7,477,000 近畿 21,990,000 3,141,429 1,727,000 大阪 8,763,000 中国 7,070,000 1,414,000 1,298,000 広島 2,738,000 四国 3,578,000 894,500 810,500 (突出県なし) 九州沖縄 14,029,000 1,753,625 1,367,500 福岡 5,103,000 全国 124,353,000 2,645,809 1,549,000 東京 14,086,000

🚀 発展:pivot_table・groupby・多次元集計への展開

※ 数表の実測値は SSDSE-B-2026(cp932, skiprows=[1])2023 年・A1101 総人口 / A4103 合計特殊出生率を本ページ用に集計したもの。 cross-tabulation・melt・simpsons-paradox は本用語集に単独ページが無いため、 リンクではなく本文中で解説した。