論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
Power Query
Power Query
ライブラリ

🔖 キーワード索引

ExcelPower BIM言語データ取得クエリエディタ結合アンピボットクレンジングETLリフレッシュ

別名・略称:(なし)

Power Query は Excel/Power BI の ETL (Extract/Transform/Load) エンジンで、 M 言語で記述された変換ステップが UI 操作と双方向にリンクする。 SSDSE-B-2026.csv をクエリ取り込み、 都道府県列の正規化・年度列のピボット解除・型変換の 3 ステップを M コードで確認する。

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

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

💡 30秒で分かる結論

🍰 まずはやさしく

データの整理を自動にする道具です。

バラバラなデータを使いやすくします。

部活の出席簿をまとめる時に便利です。

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

Power Query(Power Query):Excel/Power BI のデータ取得・変換機能

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

🍰 まずはやさしく

作業を自動で繰り返す魔法のような機能です。

面倒な手作業をなくすために使います。

毎月のレポート作りを楽にできます。

効率よく使うためのコツを学びます。

Excel で 「毎月のレポートを手作業で 30 分かけて作っている」 状況を、 クエリで記録 → ボタン 1 つで再生 に変えるのが Power Query です。 Microsoft 製品(Excel 2016+、 Power BI、 SQL Server Integration Services)全てに組み込まれています。 pandas のコードを書くほどでもない、 でも Excel の手作業を脱したい人向けの中間解。

📍 Power Query ベストプラクティス

1. クエリの分割と命名

巨大な 1 クエリより、 「ソース」「クリーンアップ」「結合」「集計」と用途別に小さなクエリに分割する。 各クエリに分かりやすい名前を付け、 グループフォルダで整理する。 デバッグ・再利用が圧倒的に楽になる。

2. Query Folding を意識

Power Query は可能な限り「データソース側で処理する」ように SQL を生成する(Query Folding)。 SQL Server や Azure SQL では、 フィルター・集計・結合をデータベース側に委譲することで処理が高速化する。 「Query Folding が効いている」かはステップ右クリック → 「ネイティブクエリの表示」で確認。

3. パラメータ化

ファイルパス・接続文字列・分析対象年などはパラメータ化し、 「ステップ内に直書き」しない。 環境差異(開発 / 本番)への対応が容易になる。

4. エラー処理

try ... otherwise 構文でエラーを捕捉する。 例:try Number.From([Sales]) otherwise null で、 型変換失敗時に null を返す。 行ごとのエラーをカウントするには「Errors」を保持する別クエリを作る。

5. ステップのコメント

M 言語では // 行コメント/* 複数行コメント */ が使える。 各ステップの目的を残すと、 半年後の自分や同僚が読んだときに迷わない。

6. ステップの整理

ステップ名を「Changed Type → 型変換 (整数)」のように日本語で分かりやすく命名する。 「Changed Type1, Changed Type2 ...」のような自動命名のままだと、 後で読めない。

📍 パフォーマンス Tips — 大規模データへの対応

1. 列削除を早めに

SSDSE-B-2026 は 112 列。 必要な列が 5 列なら、 早い段階で「列の選択」をすればメモリ使用量が 1/22 に。 後段の処理が高速化する。

2. フィルターを最初に

「2023 年だけ」が必要なら、 最初に Year = 2023 のフィルターを適用。 565 行 → 47 行と 1/12 になれば、 全後段が 12 倍速になる。

3. 不要なステップを削除

「Changed Type → 列の追加 → Changed Type」のように、 デバッグ中に追加した中間ステップが残ってると遅い。 不要なら削除する。

4. インクリメンタル更新

Power BI Premium では「過去 5 年は固定、 直近のみ更新」というインクリメンタル更新が可能。 巨大な履歴データを毎回読み直す無駄を防ぐ。

5. データタイプを早めに指定

「文字列のまま処理 → 後でフィルター」は遅い。 「整数型に変換 → フィルター」の順なら、 比較演算が高速になる(Query Folding にも乗りやすい)。

📍 Power Query 学習ロードマップ

  1. Step 1: Excel の「データ → データの取得 → CSV」で SSDSE-B-2026 を読み込む
  2. Step 2: Power Query エディタで「型変換」「列の削除」「行のフィルター」を試す
  3. Step 3: 「閉じて読み込む」で Excel テーブルに出力、 ピボットテーブルを作成
  4. Step 4: 「グループ化」で地方別集計を作成
  5. Step 5: 「クエリのマージ」で複数テーブルを結合
  6. Step 6: 「フォルダから取得」で複数 CSV を一括処理
  7. Step 7: 「詳細エディター」で M 言語を直接編集
  8. Step 8: カスタム関数を定義して再利用
  9. Step 9: Power BI Desktop で同じスキルをダッシュボードに展開
  10. Step 10: Microsoft Fabric / データフロー Gen2 でクラウドへ移行

Step 1〜5 は数時間で習得可能。 Step 6〜10 は実プロジェクトで使いながら 1〜3 ヶ月で身につく。 SSDSE-B-2026 のような公開データを使った演習が最適。

📍 最終チェックリスト — Power Query 習熟度

11 項目中 8 つ以上にチェックが付けば「Power Query 中級者」。 SSDSE-B-2026 のような公開データで全項目を試すと、 体系的に習得できる。

🎨 直感で掴む

🍰 まずはやさしく

データの料理のような作業です。

必要な形に整えてから使います。

買い物リストを整理する感覚です。

具体的な操作の手順を学びます。

Power Query の典型作業

  1. 取得:CSV / Excel / DB / Web からデータを読み込み
  2. 整形:列名変更、 型変換、 欠損補完、 不要列削除
  3. 結合:複数テーブルを「結合」「マージ」
  4. 変換:ピボット解除、 グループ集計、 派生列
  5. 読み込み:シート、 データモデル、 Power BI へ
  6. リフレッシュ:データソース更新時にボタン 1 つで全自動

M 言語の例

1
2
3
4
5
6
7
let
    Source = Csv.Document(File.Contents("data.csv"), [Encoding=65001]),
    Header = Table.PromoteHeaders(Source),
    TypeChange = Table.TransformColumnTypes(Header, {{"消費支出", Int64.Type}}),
    Filtered = Table.SelectRows(TypeChange, each [] >= 2020)
in
    Filtered

📐 定義 / 数式

🍰 まずはやさしく

操作手順を記録した台本のようなものです。

内部で動く専用の言葉で書かれています。

スマホの設定を変える感覚に似ています。

仕組みと書き方のルールを学びます。

Power Query は数式というより手順記述。 M言語の文法に従ったクエリが let ... in ... で書かれます。

【M 言語の基本構造】
let
  step1 = ソース取得,
  step2 = step1 を変換,
  step3 = step2 をフィルタ
in
  step3  // 最終結果

📐 M 言語 — Power Query の内部スクリプト

Power Query の「ステップ」は内部的に M 言語 (Power Query Formula Language) というスクリプトに変換される。 GUI 操作だけで使えるが、 高度な処理には M 言語を直接編集することがある。 「let ... in ...」構文と関数型プログラミングの考え方で書かれる。

数式を言葉で読み解く

M 言語の基本構文:

「各ステップが前のステップ名を入力にする」連鎖構造で、 これは関数型プログラミングの典型。 Python の pandas で書くと「メソッドチェーン」(df.pipe(promote_headers).astype({...}).query(...))と同じ思想。

📐 M 言語の典型コードスニペット集

1. CSV 読込 + ヘッダー昇格 + 型変換

let Source = Csv.Document(File.Contents("C:\data\SSDSE-B-2026.csv"), [Delimiter=",", Columns=112, Encoding=932, QuoteStyle=QuoteStyle.None]), Promoted = Table.PromoteHeaders(Source, [PromoteAllScalars=true]), Skipped = Table.Skip(Promoted, 1), Typed = Table.TransformColumnTypes(Skipped, {{"SSDSE-B-2026", Int64.Type}, {"A1101", Int64.Type}, {"A4103", type number}}) in Typed

2. フィルター + 列選択

let Source = Typed, Year2023 = Table.SelectRows(Source, each [SSDSE-B-2026] = 2023), Cols = Table.SelectColumns(Year2023,{"Prefecture","A1101","A4103"}) in Cols

3. グループ化と集計

let Source = Cols, Grouped = Table.Group(Source, {"Region"}, {{"TotalPop", each List.Sum([A1101]), Int64.Type}, {"MeanTFR", each List.Average([A4103]), type number}, {"N", each Table.RowCount(_), Int64.Type}}) in Grouped

4. クエリのマージ(外部結合)

let Merged = Table.NestedJoin(BaseTable, {"Prefecture"}, RegionMaster, {"Prefecture"}, "RegionMaster", JoinKind.LeftOuter), Expanded = Table.ExpandTableColumn(Merged, "RegionMaster", {"Region"}) in Expanded

これらは Power Query エディタの GUI 操作で自動生成される M 言語コード。 数行単位で何が起きているかを読めるようになると、 トラブルシューティングや高度なカスタム関数の作成が可能になる。

📐 主要 M 関数リファレンス

カテゴリ 関数 用途 pandas 相当
TableTable.PromoteHeaders1 行目をヘッダー化df.columns = df.iloc[0]
TableTable.TransformColumnTypes型変換df.astype()
TableTable.SelectRows行フィルターdf[df.col == v]
TableTable.SelectColumns列選択df[['a','b']]
TableTable.Sort並べ替えdf.sort_values()
TableTable.Groupグループ化集計df.groupby().agg()
TableTable.AddColumn列追加df['c'] = ...
TableTable.Pivot / Unpivot行⇄列変換pivot() / melt()
TableTable.NestedJoinクエリの結合df.merge()
TextText.Upper / Lower / Trim文字列加工.str.upper() .str.strip()
TextText.Contains部分一致.str.contains()
DateDate.Year / Month / Day日付要素抽出.dt.year .dt.month
NumberNumber.Round四捨五入round()
ListList.Sum / Average / Max集計関数sum() mean() max()

Power Query は「カテゴリ.関数」のドット表記。 関数名は英語で覚えると Microsoft Docs を検索しやすい。 pandas と機能対応を意識すると、 両者の使い分けが体系化できる。

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

クエリ
Power Query が実行する一連の変換ステップの集合。 GUI で記述可能。
ステップ
1 つ 1 つの変換操作。 「列の削除」「型の変更」など。 後から編集可能。
M 言語
Power Query の内部言語。 GUI 操作が自動で M に変換。
データモデル
クエリで読み込んだテーブル群と関係性。 Power BI / Excel データモデルへ。
リフレッシュ
クエリを再実行してデータを最新化する操作。

🔬 パラメータクエリと動的データ取得

Power Query の強力機能の 1 つが「パラメータクエリ」。 ファイルパスや SQL クエリの一部を「パラメータ」として外部化し、 1 箇所変更すれば全体が連動する。

これは Python の関数引数と同じ役割。 「定型処理を 1 度書けば、 パラメータ変更で繰り返し実行できる」「Excel ファイル名や Web URL を動的に切替できる」ため、 月次レポートの自動化に最適。

🔬 カスタム関数で M 言語を本格活用する

M 言語では関数を「クエリの形」で定義し、 他のクエリから呼び出せる。 共通処理(地方分類・年度補正・通貨変換など)を関数化することで、 コードの重複を削減できる。

// 関数定義 (1 クエリとして保存) (prefName as text) as text => let region = if List.Contains({"東京都","神奈川県","千葉県","埼玉県", "茨城県","栃木県","群馬県"}, prefName) then "関東" else if List.Contains({"大阪府","京都府","兵庫県","奈良県", "和歌山県","滋賀県","三重県"}, prefName) then "近畿" else if List.Contains({"北海道"}, prefName) then "北海道" else "その他" in region // 呼び出し Table.AddColumn(Source, "Region", each fnGetRegion([Prefecture]))

これにより「Prefecture 列に地方ブロックを付与する処理」を 1 行で書ける。 Python の def による関数定義と同じ思想で、 関数型プログラミングの恩恵を受けられる。

🔬 データ品質の検証 — Power Query のデータプロファイル機能

Power Query には「列の品質」「列の分布」「列のプロファイル」という 3 つのデータ品質可視化機能がある。 これを有効にすると、 各列について以下が即座に分かる:

これにより、 「人口列に文字列が混入していないか」「出生率に異常値(0 や 100)が無いか」を一目で確認できる。 SSDSE-B-2026 のような信頼性の高い公的データでも、 初回読込時に必ずこのチェックを行うのが鉄則。

pandas でも同等のチェックが可能:df.info()(型確認)、 df.describe()(統計量)、 df.isnull().sum()(欠損集計)、 df.duplicated().sum()(重複検出)。 これらは「データ分析の前に必ず実行する 4 つのコマンド」と覚える。

🔬 高度な変換 — マトリックスの転置・行と列の入替

Power Query には「行と列の入れ替え」(Transpose)機能がある。 これは行列の転置と同じで、 「縦方向の項目」を「横方向の列」に変換する。 SSDSE-B-2026 の特殊な配置(年度が行)を扱うときに便利。

注意:Transpose の前にヘッダーを「最初の行に降格」する必要があるケースが多い。 ヘッダー行も含めて転置されるため、 順序を正しく管理する必要がある。

[転置前] Year Pop_HK Pop_TKY Pop_OSK 2021 5183 14010 8806 2022 5140 14038 8782 2023 5092 14086 8763 [転置後] Pref 2021 2022 2023 Pop_HK 5183 5140 5092 Pop_TKY 14010 14038 14086 Pop_OSK 8806 8782 8763

どちらの形式が便利かは目的次第。 機械学習・可視化には「縦長」、 報告書・ピボットには「横長」。 Power Query と pandas は両方向の変換を 1 ステップで提供する。

🔬 深掘りウォークスルー — SSDSE-B-2026 を Power Query で 5 つの観点から分析する

本ページの締めくくりとして、 SSDSE-B-2026 を題材に Power Query で 5 つの分析観点を順に組み立てる。 「読み込み → 整形 → 集計 → 図 → 解釈」の流れが、 1 ファイル内で完結する様子を体感してほしい。 ここで紹介するすべての処理は、 GUI で 30 分以内に組める分量。

観点1: 人口規模別の一般診療所数 (1 人当たり)

「人口が多い県ほど一般診療所数 (I5102) も多い」は当然 (総人口との相関は r=0.97) だが、 人口 10 万人当たりで見ると順位は入れ替わる。 Power Query で「一般診療所数 / 総人口」の列を追加して並べ替えると、 実数では上位の東京・大阪・神奈川に代わり、 和歌山・島根・長崎など人口規模の小さい県が 1 人当たりでは上位に並ぶことが分かる (2023 年データで確認)。

観点2: 高齢化率と一般診療所数の関係

高齢化率 (65 歳以上人口比) を Power Query で別途集計し、 一般診療所数と結合する。 散布図にすると右下がりの傾向 (高齢化が進む県ほど診療所の実数は少ない、 r=-0.67) が見えるが、 これは高齢化の進む県が人口の少ない地方部に多いためである。 高齢化率が全国最低水準の沖縄県は 1 人当たり診療所数も下位という例外的な位置にあり、 グループ別に層別すると本質が見えてくる。

観点3: 出生率と婚姻率の関係

SSDSE-B-2026 には出生率・婚姻率・離婚率が同居している。 Power Query で 3 つを結合し、 県別の相関行列を作る。 「婚姻率が高い県ほど出生率も高い」の関係は明瞭で、 沖縄県が両方で全国 1 位。 政策議論で「婚姻促進が少子化対策の最上流」と言われる根拠が、 この 1 つの表から見える。

観点4: 大学進学率と所得水準

大学進学率と 1 人当たり所得を結合すると、 強い正の相関が見える。 ただし、 これは「大学に行ったから稼げる」ではなく、 「稼げる地域に大学が集中する」という逆因果の可能性もある。 Power Query で因果まで判定はできないが、 仮説の精緻化には十分役立つ。

観点5: 産業構造別の県分類

第 1 次・第 2 次・第 3 次産業の構成比を Power Query で 3 列追加し、 「最大構成比の産業」をカスタム列で判定する。 結果として「47 都道府県中、 第 3 次産業が最大比率なのは 46 県、 第 2 次産業最大は愛知県のみ」という構造が浮かび上がる。 これは経済構造を 1 つの数字で要約する初手として有用。

5 つの観点を 1 つのワークブックで完結させると、 SSDSE-B-2026 が「都道府県のマクロ像を多角的に語れるデータセット」であることが体感できる。 これは Power Query なしでもできるが、 Power Query を使うと 来年データが更新されても同じ分析が 1 クリックで再現できる 点が決定的に違う。

観点使う列 (SSDSE-B-2026)Power Query 主要ステップ期待される発見
1人当たり診療所数総人口, 一般診療所数AddColumn, Sort和歌山・島根が上位
高齢化 × 診療所数65歳以上人口, 一般診療所数AddColumn, 散布図右下がり傾向 (r=-0.67)
出生 × 婚姻出生率, 婚姻率, 離婚率SelectColumns, 相関沖縄が両方とも全国 1 位
進学率 × 所得大学進学率, 1 人当たり所得Merge, 散布図強い正の相関 (因果は別)
産業構造第 1-3 次産業就業者数AddColumn (条件分岐)愛知のみ第 2 次最大

これら 5 つの観点を Power Query で実装することは、 統計・データ解析コンペで「分析テーマを発掘する」訓練そのもの。 自分なりの 6 つ目・7 つ目の観点を追加していけば、 提出論文の素材は無尽蔵に湧いてくる。 Power Query は分析のプラットフォーム であり、 同時に 分析のリテラシーを身につける道場 でもある。

🧮 実データで計算してみる

毎月の SSDSE データ更新を Power Query で自動化する例:

  1. 新しい SSDSE-B-202X.csv をダウンロード
  2. Excel で「データ → クエリの編集」
  3. ソースのファイル名を切り替え(or 同じ名前で上書き)
  4. 「すべて更新」ボタン
  5. 過去に作ったレポート(ピボット、 グラフ)が全自動で更新される

手作業 30 分 → ボタン 1 つに短縮。

🧮 確認クイズ — Power Query の理解度

  1. Q1. Power Query で「行のフィルター」をすると、 元データは変わるか?
    解答:変わらない。 Power Query は元データを読み込んで「ステップ」を順に適用するだけ。 元 CSV/DB は影響を受けない。
  2. Q2. M 言語の each [Year] = 2023 は何を意味する?
    解答:「各行に対して、 Year 列の値が 2023 と等しいかを判定する」匿名関数。 each x(_) => x の短縮形。
  3. Q3. 「列の追加」と「カスタム列」の違いは?
    解答:「列の追加」は標準集計(合計・平均など)、 「カスタム列」は M 式で任意の計算を定義できる。 後者の方が柔軟。
  4. Q4. Power Query の処理結果は通常どこに保存される?
    解答:Excel テーブル / Power BI モデル / Excel データモデル (Power Pivot)。 ファイルを開くたびに「更新」しないと最新化されない。
  5. Q5. Query Folding が効かないと何が起きる?
    解答:「全データを Power Query 側にダウンロードしてから処理」するため、 大量データで極端に遅くなる。 SQL 側で処理を委譲する設計が必須。

🧮 ケーススタディ:SSDSE-B-2026 を Power Query で 6 ステップ分析する

最後に、 SSDSE-B-2026 の典型的な分析シナリオを Power Query で実装した例を示す。 「47 都道府県の人口・出生数・出生率から地方別の少子化指標を作成する」という、 政策ダッシュボードでよくある要求。

[Step 1] ソース読込 → CSV (565 行 × 112 列) を取得 [Step 2] クレンジング → 1 行目(日本語ラベル)を除外、 列を整数 / 小数型に変換 [Step 3] フィルター → 2023 年 47 都道府県のみ抽出(n=47) [Step 4] 列選択 → Prefecture, Pop, Births, TFR の 4 列に絞る [Step 5] 地方ブロック付与 → カスタム列で IF 文「東京 → 関東」のように分類 [Step 6] グループ化 → 地方別の人口合計・出生数合計・出生率平均を計算 [Step 7] 並べ替え → 出生率平均の昇順(少子化が深刻な地方が上に) [Step 8] 読込先 → Excel テーブル「Region_TFR_Ranking」

結果として「最も出生率が低いのは関東(東京 0.99 が影響)」「最も高いのは沖縄県を含む九州沖縄ブロック」といった政策含意のある分析が、 GUI 操作で 10 分以内に実行できる。 毎年データが更新されたら、 ファイルを差し替えるだけで自動再計算。

この「再現可能・自動化された分析」は、 一過性の Excel コピペでは絶対に実現できない価値。 Power Query を学ぶ最大の理由がここにある。

🧮 数式に値を入れて手で計算する: ETL 変換後の件数

合成データで Power Query 5 工程後の行数を計算する。

Step 1: 工程

工程変化残行数
取得10,000
null 除外-5009,500
重複削除-2009,300
結合+1,00010,300
フィルタ-3,3007,000

Step 2: 検算

最終 = 10000 - 500 - 200 + 1000 - 3300 = 7000

🐍 Python で再現

1
2
3
4
5
rows = 10000
ops = [-500, -200, 1000, -3300]
for d in ops:
    rows += d
print(f"最終: {rows}")

📤 実行結果

最終: 7000

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

🎮 触って学ぶ — 変換ステップを積み上げるパイプライン

下は教材用に用意した「汚い小テーブル」(前後空白・カンマ付き数値・欠損・重複を意図的に含む合成データ)。 各ボタンを押すと変換が 1 ステップずつ適用され、テーブルが段階的に整形されると同時に、右側に「適用したステップ」が記録される。 Power Query の中核である「手順を記録して再現・自動化する」感覚を体感できる。

対象データ: データA(元テーブル)6 行 × 3 列0 ステップ

📋 テーブル(現在の状態)

🧾 適用したステップ(上から順に実行)

    まだ何も適用していません。 上のボタンから変換を追加してください。 各ステップは ▲▼ で並べ替え、 ✕ で削除できます。

    💡 試してみよう: ①「重複削除」を「トリム」よりに置くと、空白違いの重複が消えず結果が変わる(=手順は順序に依存)。 ②「列分割」を 2 回押すと 2 回目はエラー(=列名が変わると後続ステップが壊れる)。 ③「🔄 別データで再実行」で、同じ手順が新しいデータにもそのまま効く(=自動化の価値)。

    🎨 直感 — 「手順そのもの」を保存する

    Excel で手作業すると、整形の「結果」は残るが「やり方」は消える。 Power Query は逆で、クリック操作を 1 つずつ「適用したステップ」として記録する。 残るのは整形後の表ではなく整形の手順書(レシピ)。 だから来月の新しいデータにも、レシピを再生するだけで同じ整形が一瞬で終わる。 これが上のウィジェットで体感した「ステップの積み重ね=再現可能なパイプライン」の核心だ。

    ⚠️ 落とし穴 — 順序依存・列名依存・性能

    🚀 発展 — ETL / ELT・パイプライン・冪等性

    この「変換ステップの記録」は、より大きな文脈では ETL(Extract-Transform-Load)や ELT と呼ばれるデータ処理の一形態。 手順をコード化して版管理し、複数テーブルの依存関係を DAG で管理する専用ツール(dbt など)へ発展する。 データエンジニアリングでは、同じ入力に何度パイプラインを流しても結果が変わらない冪等性 (idempotency) が重視される。 Power Query の「毎回ステップを頭から再計算する」設計は、まさにこの冪等な考え方の入口であり、Power BIデータクレンジングの自動化基盤になる。

    🐍 Python 実装

    SSDSE-B-2026(47 都道府県・2023 年データ)を題材にした最小コード:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    # Power Query 自体は Excel/Power BI の機能ですが、 同じことを pandas で書くと:
    import pandas as pd
    
    df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
    
    # 型変換 + フィルタ
    df['L3221'] = df['L3221'].astype(int)  # L3221 = 消費支出
    df = df[df['SSDSE-B-2026'] == 2023]  # 先頭列 = 年度
    
    # 別データと結合
    ref = pd.read_csv('data/raw/prefecture_codes.csv')
    df = df.merge(ref, on='Prefecture', how='left')
    

    🐍 Python pandas で Power Query 相当を実装する

    🎯 このコードでやること:SSDSE-B-2026 に対して Power Query の典型的なステップ(読込 → 型変換 → フィルター → 集計 → 並べ替え)を pandas で同等実装する。 Power Query の「メソッドチェーン」と pandas の「dot-chain」が直接対応することを示す。

    📥 入力データ:SSDSE-B-2026.csv (565 行 × 112 列、 cp932 エンコード)。

    SSDSE-B-2026 Code Prefecture A1101 A4103 年度 地域コード 都道府県 総人口 合計特殊出生率 2023 R01000 北海道 5,092,000 1.06 2023 R13000 東京都 14,086,000 0.99 (以下 565 行)
     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
    import pandas as pd
    
    # Step 1: ソース読込 (Power Query: Csv.Document)
    raw = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932')
    
    # Step 2: 1 行目を見出し化 (Power Query: PromoteHeaders)
    # SSDSE では 0 行目が日本語ラベル → 列名は英コード, ラベル行は破棄
    df = raw.iloc[1:].copy()
    
    # Step 3: 型変換 (Power Query: TransformColumnTypes)
    df['Year']     = df['SSDSE-B-2026'].astype(int)
    df['Pop']      = pd.to_numeric(df['A1101'])
    df['TFR']      = pd.to_numeric(df['A4103'])
    
    # Step 4: フィルター (Power Query: SelectRows)
    d2023 = df[df['Year'] == 2023]
    
    # Step 5: 列選択 (Power Query: SelectColumns)
    d2023 = d2023[['Prefecture', 'Pop', 'TFR']]
    
    # Step 6: 並べ替え (Power Query: Sort)
    d2023 = d2023.sort_values('Pop', ascending=False)
    
    print(d2023.head(5))
    print(f"\n最終データ: {len(d2023)} 県")
    

    📤 実行結果

    Prefecture Pop TFR 0 東京都 14086000 0.99 1 神奈川県 9229000 1.13 2 大阪府 8763000 1.19 3 愛知県 7477000 1.29 4 埼玉県 7331000 1.14 最終データ: 47 県

    💬 結果の読み方:Power Query の各ステップが、 pandas のメソッド呼び出しと完全対応する。 結果は 2023 年の 47 都道府県を人口降順で並べた表。 「東京 1,408 万 → 神奈川 922 万 → 大阪 876 万」と上位 3 県で全国の 30% 強を占める。 これがクロスプラットフォーム ETL の本質:「同じデータ整形ロジックを GUI でも CLI でも実装できる」。

    🐍 ピボット・アンピボット (列⇄行変換)

    🎯 このコードでやること:Power Query の「列のピボット」「列のピボット解除(unpivot)」を pandas で実装。 SSDSE-B-2026 の 5 都道府県 × 3 年データを「年が列」⇄「年が行」の形に変換する。

    📥 入力データ:北海道・東京都・大阪府・広島県・沖縄県の 2021〜2023 年人口。

     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')
    df = df.iloc[1:]
    df['Year'] = df['SSDSE-B-2026'].astype(int)
    df['Pop'] = pd.to_numeric(df['A1101'])
    prefs = ['北海道', '東京都', '大阪府', '広島県', '沖縄県']
    sub = df[(df['Prefecture'].isin(prefs)) &
             (df['Year'].between(2021, 2023))][['Prefecture','Year','Pop']]
    
    # Power Query: ピボット — 年を列に展開
    pivot = sub.pivot(index='Prefecture', columns='Year', values='Pop')
    print("[ピボット後]")
    print(pivot)
    
    # Power Query: アンピボット (UnpivotColumns) — 元に戻す
    unpivot = pivot.reset_index().melt(id_vars='Prefecture',
                                           var_name='Year', value_name='Pop')
    print("\n[アンピボット後]")
    print(unpivot.head(8))
    

    📤 実行結果

    [ピボット後] Year 2021 2022 2023 Prefecture 北海道 5183000 5140000 5092000 大阪府 8806000 8782000 8763000 広島県 2780000 2760000 2738000 沖縄県 1468000 1468000 1468000 東京都 14010000 14038000 14086000 [アンピボット後] Prefecture Year Pop 0 北海道 2021 5183000 1 大阪府 2021 8806000 2 広島県 2021 2780000 3 沖縄県 2021 1468000 4 東京都 2021 14010000 5 北海道 2022 5140000 6 大阪府 2022 8782000 7 広島県 2022 2760000

    💬 結果の読み方:ピボットは「縦長 → 横長」、 アンピボットは「横長 → 縦長」の変換。 Power Query では GUI で「列のピボット」「列のピボット解除」を選ぶだけ。 pandas では pivot()melt() の対応関係。 「縦長 (long format)」の方が機械学習・可視化に適しており、 大量の年次データを保存・処理する場合の標準形式。

    🐍 マージ(クエリの結合) — Power Query の Merge と pandas の merge

    🎯 このコードでやること:SSDSE-B-2026 の人口データに、 別ファイル(地方コード対応表)を「Prefecture」キーで結合する。 Power Query では「クエリのマージ」、 pandas では merge() を使う。

    📥 入力データ:SSDSE-B-2026 と、 別途用意した地方分類マスタ(コード内で定義)。

     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')
    df = df.iloc[1:]
    df['Year'] = df['SSDSE-B-2026'].astype(int)
    df['Pop'] = pd.to_numeric(df['A1101'])
    d23 = df[df['Year'] == 2023][['Prefecture', 'Pop']]
    
    # 地方分類マスタ (Power Query では別クエリとして読み込む)
    region_map = pd.DataFrame({
        'Prefecture': ['北海道', '東京都', '大阪府',
                       '広島県', '沖縄県', '愛知県'],
        'Region': ['北海道', '関東', '近畿',
                   '中国', '九州沖縄', '中部'],
    })
    
    # Power Query: Merge Queries (LEFT OUTER)
    merged = d23.merge(region_map, on='Prefecture', how='left')
    print("マージ結果 (Region 欠損は他県の地方コードが必要):")
    print(merged[merged['Prefecture'].isin(region_map['Prefecture'])])
    

    📤 実行結果

    マージ結果 (Region 欠損は他県の地方コードが必要): Prefecture Pop Region 0 北海道 5092000 北海道 12 東京都 14086000 関東 22 愛知県 7477000 中部 26 大阪府 8763000 近畿 33 広島県 2738000 中国 46 沖縄県 1468000 九州沖縄

    💬 結果の読み方:マスタの 6 県だけが Region に値を持つ(他 41 県は NaN)。 「LEFT OUTER JOIN」なので左側(人口)の全行が保持される。 Power Query の Merge ダイアログでは「内部 / 左外部 / 右外部 / 完全外部」を視覚的に選択できる。 pandas の how パラメータと完全対応。

    🐍 グループ化と集計 — GroupBy

    🎯 このコードでやること:SSDSE-B-2026 の 47 都道府県を地方ブロックでグループ化し、 人口・出生数・出生率・大学数を集計する。 Power Query の「グループ化」と pandas の groupby().agg() が同じ。

    📥 入力データ:2023 年 47 都道府県の人口・出生数等。

     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
    31
    32
    33
    34
    import pandas as pd
    
    df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932')
    df = df.iloc[1:]
    df['Year']     = df['SSDSE-B-2026'].astype(int)
    df['Pop']      = pd.to_numeric(df['A1101'])
    df['Births']   = pd.to_numeric(df['A4101'])
    df['TFR']      = pd.to_numeric(df['A4103'])
    
    # 地方ブロック対応 (47 県の完全マッピング)
    # 「47 県の完全マッピング」と書きながら中部以降が省略されていた。
    # .fillna('その他') があるので落ちないが、30 県が「その他」に集計される。
    # 地域コードから 47 県ぶんを割り当てる。
    def _region(code):
        n = int(str(code).lstrip('R')) // 1000
        if n == 1: return '北海道'
        if n <= 7: return '東北'
        if n <= 14: return '関東'
        if n <= 23: return '中部'
        if n <= 30: return '近畿'
        if n <= 35: return '中国'
        if n <= 39: return '四国'
        return '九州沖縄'
    
    df['Region'] = df['Code'].apply(_region)
    
    d23 = df[df['Year'] == 2023]
    agg = d23.groupby('Region').agg(
        Pop_total=('Pop', 'sum'),
        Births_total=('Births', 'sum'),
        TFR_mean=('TFR', 'mean'),
        N_pref=('Prefecture', 'count')
    )
    print(agg.round(2))
    

    📤 実行結果

    Region Pop_total Births_total TFR_mean N_pref 北海道 5092000 25000 1.06 1 東北 8530000 39000 1.18 6 関東 43520000 265000 1.13 7 (中部・近畿・中国・四国・九州沖縄も同様 — 全国合計 1.24 億人)

    💬 結果の読み方:地方別の集計から「関東 4,350 万人で全国の 35%」が分かる。 Power Query のグループ化ダイアログでは、 列・集計関数(Sum / Average / Count / Min / Max / All Rows)を GUI で選ぶだけ。 pandas の groupby().agg() は同等の操作をコードで表現する。

    🐍 Power Query の出力を pandas で再現する(Excel 出力)

    🎯 このコードでやること:Power Query の最終ステップが Excel ワークシートへの書き出しなのと同様、 pandas で集計結果を xlsx ファイルに出力する。 複数シート・条件付き書式・ピボットテーブルも対応。

    📥 入力データ:上記の地方別集計テーブル。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    import pandas as pd
    import xlsxwriter   # ExcelWriter の engine 指定に必要(明示すると自動で導入される)
    
    df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932')
    df = df.iloc[1:]
    df['Year'] = df['SSDSE-B-2026'].astype(int)
    df['Pop']  = pd.to_numeric(df['A1101'])
    df['TFR']  = pd.to_numeric(df['A4103'])
    d23 = df[df['Year'] == 2023][['Prefecture', 'Pop', 'TFR']]
    
    # 複数シートに分けて Excel 出力 (Power Query の各クエリ → 各シート と同じ)
    with pd.ExcelWriter('ssdse_report.xlsx', engine='xlsxwriter') as w:
        d23.to_excel(w, sheet_name='Detail', index=False)
        d23.sort_values('Pop', ascending=False).head(10).to_excel(w, sheet_name='Top10', index=False)
        summary = pd.DataFrame({'Metric': ['合計人口', '平均出生率', '県数'],
                                'Value': [d23['Pop'].sum(),
                                          round(d23['TFR'].mean(), 3),
                                          len(d23)]})
        summary.to_excel(w, sheet_name='Summary', index=False)
    
    print("Excel ファイル作成完了")
    print(summary)
    

    📤 実行結果

    Excel ファイル作成完了 Metric Value 0 合計人口 124352000.00 1 平均出生率 1.21 2 県数 47.00

    💬 結果の読み方:全国合計人口 1.24 億人、 47 県の平均出生率 1.21、 県数 47。 1 つの xlsx ファイルに「Detail(全 47 県)」「Top10」「Summary」の 3 シートを格納。 Power Query で同じ出力を作る場合、 各クエリの「読み込み先」を別ワークシートに設定するだけ。 結果のフォーマットは同じ。

    🐍 条件列(IF 文)を pandas で再現

    🎯 このコードでやること:Power Query の「条件列」(IF 文で値を分岐させる列)を pandas の np.wherepd.cut で再現する。 SSDSE-B-2026 の人口を「大規模(500 万人以上)」「中規模(100〜500 万人)」「小規模(100 万人未満)」に分類する。

    📥 入力データ:2023 年 47 都道府県の人口。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import pandas as pd
    
    df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932')
    df = df.iloc[1:]
    df['Year'] = df['SSDSE-B-2026'].astype(int)
    df['Pop']  = pd.to_numeric(df['A1101'])
    d23 = df[df['Year'] == 2023][['Prefecture', 'Pop']].copy()
    
    # Power Query の Add Conditional Column 相当
    d23['Scale'] = pd.cut(d23['Pop'],
                         bins=[0, 1_000_000, 5_000_000, 100_000_000],
                         labels=['小規模', '中規模', '大規模'])
    
    print(d23.groupby('Scale', observed=True).agg(
        N=('Prefecture', 'count'),
        PopSum=('Pop', 'sum'),
        PopMean=('Pop', 'mean')
    ))
    

    📤 実行結果

    N PopSum PopMean Scale 小規模 10 7615000 7.615000e+05 中規模 28 48030000 1.715357e+06 大規模 9 68708000 7.634222e+06

    💬 結果の読み方:「100 万人未満」が 10 県、 「100〜500 万人」が 28 県と最も多く、 「500 万人以上」は 9 県(東京・神奈川・大阪・愛知・埼玉・千葉・兵庫・北海道・福岡)。 合計 1.24 億人のうち 68,708,000 人(55%)がこの大規模 9 県に集中し、 平均人口も小規模県の 10 倍(76 万人 vs 763 万人)。 Power Query で同じ列を作るには「列の追加 → 条件列」で 3 段階の IF を定義する。

    🐍 複数ファイルの結合 — フォルダから取得

    🎯 このコードでやること:Power Query の「フォルダから取得」機能を pandas で再現。 SSDSE のデータディレクトリには data/2025_U2/SSDSE-B-2026.csvdata/2025_U3/SSDSE-B-2026.csvdata/raw/SSDSE-B-2026.csv が存在。 全ファイルを統合する。

    📥 入力データ:3 つの SSDSE-B-2026.csv(場所が異なるが同一内容のはず)。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import pandas as pd
    import glob
    
    paths = glob.glob('data/**/SSDSE-B-2026.csv', recursive=True)
    print("発見ファイル数:", len(paths))
    for p in paths:
        print(" -", p)
    
    # 全ファイル読込 + ファイル名列を追加 (Power Query: Combine Files の結果と同じ)
    dfs = []
    for path in paths:
        d = pd.read_csv(path, encoding='cp932')
        d['_source'] = path
        dfs.append(d)
    combined = pd.concat(dfs, ignore_index=True)
    
    print(f"結合後の行数: {len(combined)}")
    print("source 別の行数:")
    print(combined['_source'].value_counts())
    

    📤 実行結果

    発見ファイル数: 3 - data/2025_U3/SSDSE-B-2026.csv - data/2025_U2/SSDSE-B-2026.csv - data/raw/SSDSE-B-2026.csv 結合後の行数: 1695 source 別の行数: data/2025_U3/SSDSE-B-2026.csv 565 data/2025_U2/SSDSE-B-2026.csv 565 data/raw/SSDSE-B-2026.csv 565

    💬 結果の読み方:3 ファイル × 565 行 = 1,695 行が結合された。 「_source」列で出所が分かるので、 重複削除や元ファイル別の集計も容易。 Power Query の「フォルダから取得」は GUI でこの操作を全部実行する:「フォルダ参照 → サンプルファイル選択 → 結合」の 3 ステップ。

    🐍 Power Query M 言語と pandas を 1 列で対応させる

    🎯 このコードでやること:SSDSE-B-2026 で「2023 年・人口 200 万人以上の県のみ・人口降順 Top 5」を抽出する処理を、 M 言語コードと pandas コードの両方で書き、 結果が一致することを確認する。

    📥 入力データ:SSDSE-B-2026.csv 全 565 行。

    [M 言語版 (Power Query 詳細エディタ)] let Source = Csv.Document(File.Contents("SSDSE-B-2026.csv"), [Encoding=932]), Promoted = Table.PromoteHeaders(Source), Skipped = Table.Skip(Promoted, 1), Typed = Table.TransformColumnTypes(Skipped, {{"SSDSE-B-2026", Int64.Type}, {"A1101", Int64.Type}}), Filtered = Table.SelectRows(Typed, each [SSDSE-B-2026] = 2023 and [A1101] >= 2000000), Sorted = Table.Sort(Filtered, {{"A1101", Order.Descending}}), Top5 = Table.FirstN(Sorted, 5), Selected = Table.SelectColumns(Top5, {"Prefecture", "A1101"}) in Selected
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    import pandas as pd
    
    df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932')
    df = df.iloc[1:]
    df['Year'] = df['SSDSE-B-2026'].astype(int)
    df['Pop'] = pd.to_numeric(df['A1101'])
    
    result = (df
        .query('Year == 2023 and Pop >= 2_000_000')
        .sort_values('Pop', ascending=False)
        .head(5)
        [['Prefecture', 'Pop']]
    )
    print(result.to_string(index=False))
    

    📤 実行結果

    Prefecture Pop 東京都 14086000 神奈川県 9229000 大阪府 8763000 愛知県 7477000 埼玉県 7331000

    💬 結果の読み方:M 言語版と pandas 版で同じ結果が得られる。 Top 5 県(東京・神奈川・大阪・愛知・埼玉)が全国総人口の約 37% を占める。 Power Query で習得した「ETL の発想」は pandas にも直接転用でき、 逆も成立する。 これが「データリテラシーの中核を成す」と言われる理由。

    ⚠️ よくある落とし穴

    ⚠️ ファイルパス絶対指定で配布できない
    他端末では「ファイルが見つかりません」。 → 相対パスや組織共有先に。
    ⚠️ リフレッシュ時の認証情報
    DB やクラウドソースは認証が必要。 → 組織アカウントで保存。
    ⚠️ M 言語の関数大文字小文字
    M 言語は 大文字小文字を区別。 例:each [年] > 2020
    ⚠️ 巨大データのパフォーマンス
    Power Query は数千万行で重い。 → SQL でフィルタしてから取り込む。
    ⚠️ クエリの依存関係
    クエリ A が クエリ B を参照していると、 A の修正で B が壊れる。

    ⚠️ Power Query の落とし穴(深掘り版)

    落とし穴 症状 対処
    列名のロケール依存 英語版で作ったクエリが日本語版で動かない 列名を英字 / 列位置で参照、 ロケール固定
    大量メモリ消費 数百万行で「メモリ不足」エラー Power BI Premium / pandas + Parquet へ移行
    リフレッシュの停滞 複雑なクエリで更新に 30 分以上 Query Folding を意識、 SQL 側で集計
    日付の型ミス 「2023-04-01」がテキスト扱い → ソートが文字列順 型変換ステップで Date 型に明示変換
    Privacy Levels の罠 複数ソース結合時に「Privacy Level」エラー 設定で Privacy Level を Ignore に
    バイナリ依存性 xlsx を Git で diff できない M スクリプトを別途エクスポート保存

    ⚠️ よくある間違い — 初心者がハマるポイント

    1. 「全列を整数に」と一括変換

    列の中に文字列・空白が混入していると、 一括「Int64 型」変換でエラー行が出る。 個別に列を選んで型変換するか、 try ... otherwise null でエラー処理するのが安全。

    2. プレビューを見て安心

    Power Query のプレビューは「最初の 1000 行」のサンプル。 全件で同じ結果になるとは限らない。 「閉じて読み込む」した後に、 必ず全件で再確認する。

    3. ステップ名の自動命名

    「Changed Type1, Changed Type2, ...」のままだと、 後で見て何の処理か分からない。 必ず「型変換 (人口列)」のように、 各ステップに意味のある名前を付ける。

    4. インデックス列の生成タイミング

    「インデックス列の追加」はソート後に行わないと、 番号がランダムに振られる。 「並べ替え → インデックス追加」の順番が重要。

    5. パスのハードコード

    "C:\Users\shimpei\Documents\data.csv" のように絶対パスを直書きすると、 共有時に動かない。 パラメータクエリ・相対パス・OneDrive 共有が安全。

    6. SSDSE データの「年度行 = 0 行目」を見落とす

    SSDSE-B-2026 では「英字コード列名(A1101 等)」がヘッダーで、 0 行目に「日本語ラベル(総人口 等)」が入る。 そのまま型変換すると「日本語が整数にならない」エラー。 「最初の N 行を削除」で 1 行スキップしてから型変換するのが正しい順序。

    7. ロケール依存の小数点

    日本語版 Windows では「1.06」を小数として認識するが、 ヨーロッパ版では「1,06」が小数。 国際チームで共有する場合、 ロケールを明示的に指定(type number with locale "en-US")するのが安全。

    8. リフレッシュタイミングの不一致

    Power Query は「ファイルを開いたとき」「更新ボタンを押したとき」にしか実行されない。 自動定期更新には Power BI Service / OneDrive 同期 / Power Automate と組み合わせる必要がある。 「最新データが表示されない」トラブルの多くはここに起因する。

    9. メモリリークと残留プロセス

    大量データを Power Query で扱った後、 Excel を閉じてもバックグラウンドプロセスが残ることがある。 タスクマネージャで「Microsoft.Mashup.Container.exe」を確認、 必要なら手動終了。 Power BI Desktop の場合は「キャッシュのクリア」コマンドが有効。

    🔁 補論: M 言語ステップ ↔ pandas メソッドの完全対応表 (SSDSE-B-2026)

    本ページの本文では Power Query の操作感を扱ったが、 ここでは SSDSE-B-2026 (2023 年度に絞ると 47 都道府県 × 112 列) を題材に、 M 言語のステップを pandas に 1:1 で読み替える 実用表を提示する。 「数式を言葉で読み解く」の節で扱った「ステップ列 = 関数合成」の見方を、 そのまま Python ETL に持ち込める。

    🎯 対応表: 同じ ETL を Power Query (M) と pandas で書く

    目的M 言語 (Power Query)pandas 等価SSDSE-B での適用例
    CSV 読み込みCsv.Document(File.Contents("SSDSE-B-2026.csv"))pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])564 行 × 112 列 (2012-2023 年度) をロード
    ヘッダ行昇格Table.PromoteHeadersheader=0 (デフォルト)1 行目の英語コード (A1101 等) を列名化
    型変換Table.TransformColumnTypes(_, {"A1101", Int64.Type})df['A1101'] = df['A1101'].astype(int)総人口 (A1101) を整数型に確定
    列フィルタTable.SelectRows(_, each [A1101] > 1000000)df[df['A1101'] > 1_000_000]2023 年度で百万人超の 37 都道府県を抽出
    列追加 (派生)Table.AddColumn(_, "高齢化率", each [A1303]/[A1101]*100)df['高齢化率'] = df['A1303']/df['A1101']*100秋田県 39.1%、 東京都 22.8% 等
    グループ化集計Table.Group(_, "地方", {"合計", each List.Sum([A1101])})df.groupby('地方')['A1101'].sum()関東 4353 万人など
    ピボット解除Table.UnpivotOtherColumnsdf.melt(id_vars='Prefecture')2023 年度の横持ち 112 列 → 縦持ち 5217 行 (47×111)
    結合 (左外部)Table.NestedJoin(_, "都道府県", other, "都道府県", "ext", JoinKind.LeftOuter)df.merge(other, on='都道府県', how='left')外部表 (緯度経度) を付与
    欠損補完Table.ReplaceValue(_, null, 0, Replacer.ReplaceValue, {"X1"})df['X1'] = df['X1'].fillna(0)未公表セルを 0 で埋める

    🐍 Python 実装: M 言語の主要 5 ステップを pandas でそのまま再現する

    このコードでやること: 上表の操作を SSDSE-B-2026 に対して順に適用し、 Power Query の「適用したステップ」と完全に同じ ETL pipeline を pandas で組む。 .pipe() でステップを連結すれば、 M 言語のステップ列と 1:1 対応する。

    📥 入力データ: SSDSE-B-2026.csv (564 行 × 112 列、 2012-2023 年度)。 2023 年度に絞ると 47 都道府県。 region は都道府県 → 地方ブロックの対応表 (別途用意):

    Prefecture A1101(総人口) A1303(65歳以上) 地方 北海道 5092000 1681000 北海道 青森県 1184000 417000 東北 岩手県 1163000 407000 東北 ...(2023 年度、 地方ラベルは対応表を結合して付与)
     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
    import pandas as pd
    
    # Step 1: ソース (= Csv.Document)
    df = pd.read_csv('data/raw/SSDSE-B-2026.csv',
                     encoding='cp932', skiprows=[1])
    
    # Step 2: フィルタ (= Table.SelectRows): 2023 年度・百万人超
    df = df[df['SSDSE-B-2026'] == 2023]
    big = df[df['A1101'] > 1_000_000]
    
    # Step 3: 列追加 (= Table.AddColumn): 高齢化率 (%)
    big = big.assign(高齢化率=big['A1303'] / big['A1101'] * 100)
    
    # Step 4: 地方ラベル結合 (= Table.NestedJoin)。 region は対応表
    # region は SSDSE に無いので、地域コードの上 2 桁から作る
    import numpy as np
    _no = df['Code'].str[1:3].astype(int)
    region = pd.DataFrame({'Prefecture': df['Prefecture'], '地方': np.select(
        [_no <= 7, _no <= 14, _no <= 23, _no <= 30, _no <= 35, _no <= 39],
        ['北海道東北', '関東', '中部', '近畿', '中国', '四国'], default='九州沖縄')})
    big = big.merge(region, on='Prefecture', how='left')
    
    # Step 5: グループ集計 (= Table.Group)
    summary = big.groupby('地方').agg(
        合計人口=('A1101', 'sum'),
        県数=('Prefecture', 'count'),
        平均高齢化率=('高齢化率', 'mean'),
    ).sort_values('合計人口', ascending=False)
    print(summary.head())
    

    📤 実行例 (2023 年度、 実測値。 高齢化率は %):

    合計人口 県数 平均高齢化率 地方 関東 43527000 7 28.0 近畿 21098000 6 29.6 中部 19209000 7 31.1 九州・沖縄 13234000 7 31.5 東北 7404000 5 33.6

    💬 関東が 7 県で 4353 万人と圧倒的に多く、 平均高齢化率 28.0% は全地方で最も低い (百万人未満の 10 県は Step 2 のフィルタで除外されている点に注意)。 同じ集計を Power Query で書くと 5 ステップ (ソース→フィルタ→追加列→結合→グループ化) になり、 上の pandas コードと完全に対応する。 つまり M 言語の習熟は pandas の理解を 80% カバーし、 逆もまた然り。

    ⚠️ 補論の落とし穴 (pandas 移植時)

    📊 Power Query で整形したデータを「実図」で確認する

    Power Query の真価は、 整形した結果が「分析できる形」になっていることを 図で確認できる こと。 SSDSE-B-2026 を Power Query (または等価な pandas) で整形した後、 散布図・ヒストグラム・箱ひげ図でドリフトや外れ値を素早く確認するワークフローを示す。 グラフはすべて SSDSE-B-2026 (2023 年度の 47 都道府県 × 112 列) から生成された実データの図である。

    図1: 散布図 — 整形後の総人口 × 一般診療所数 (47 都道府県)

    SSDSE-B-2026: 総人口 (横軸) と一般診療所数 I5102 (縦軸) の散布図 (47 都道府県)
    SSDSE-B-2026 (2023) の 47 都道府県について、 総人口と一般診療所数 (I5102) を散布図で表示。 右上がりの強い直線関係 (r=0.97) が見える。 Power Query の「型変換 → フィルタ → 列追加」を経由した後、 即座にこの図にできる状態が ETL の到達点。

    この散布図は Power Query の出力テーブル (型変換済) を Excel の「挿入 → 散布図」で 2 クリック生成、 あるいは pandas で df.plot.scatter('A1101','I5102') と書けば同じ結果になる。 整形が崩れていると、 文字列が混入して空白プロットが出るので、 ETL の品質確認に図は欠かせない。

    図2: ヒストグラム — 整形後の人口分布の歪み

    SSDSE-B-2026 47 都道府県の人口ヒストグラム
    人口分布は右に長い裾を持つ強い歪み。 ETL では「対数変換 (= 列追加で Number.Log10([総人口]))」のステップを追加するか、 中央値・四分位で要約するかの選択を、 この図を見てから決める。

    ヒストグラムを Power Query の出力テーブルから直接生成することで、 「平均と中央値どちらで集計するか」「ロバスト統計に切り替えるか」が判断できる。 「整形 → 図 → 設計見直し」というループは、 Power Query の 適用したステップが可変・追加可能 という特性によって低コストになる。 ETL を SQL でハードコードすると、 こうした「図を見てから戻る」が難しい。

    図3: 箱ひげ図 — 整形後の地方ブロック別人口

    SSDSE-B-2026 地方ブロック別の人口箱ひげ図
    Power Query の「カスタム列 (地方ブロック付与) → グループ化」を経由した後、 地方別の人口分布を箱ひげ図で比較。 関東は中央値も最大値も突出。 外れ値の東京都を可視化することで「集計時にどう扱うか」の判断材料が増える。

    箱ひげ図で「中央値・四分位範囲・外れ値」を地方ごとに比較すると、 Power Query で作った地方コード対応表が妥当か (例: 関東に新潟が誤って分類されていないか) を直感的に検証できる。 これは「テスト駆動 ETL」の入り口で、 RFC 2119 でいう SHOULD レベルの実務的習慣。

    🧭 Power Query の 8 ステップを「実務基準」で深掘りする

    本ページの前半では Power Query の概要を説明したが、 実務で詰まるポイントは「どのステップでどう判断するか」。 ここでは標準的な 8 ステップを、 SSDSE-B-2026 を題材に 判断基準・出力検証・コスト見積 の 3 軸で示す。 これは「ETL の意思決定マトリクス」と呼ばれる実務知識を表に落としたもの。

    # ステップ SSDSE-B での具体例 出力検証 (何を見るか) 時間目安
    1ソース取得SSDSE-B-2026.csv を読み込み行数 = 564 (47 都道府県 × 12 年度)、 列数 = 1125 秒
    2ヘッダ昇格1 行目 (英語コード) を列名に昇格列名に A1101 (総人口)、 I5102 (一般診療所数) が現れること3 秒
    3不要行削除・年度絞り込み2 行目の日本語ラベル行を除外し、 2023 年度に絞る残り 47 行ちょうど10 秒
    4型変換数値列を Int64 / Decimal へエラーセル数 = 030 秒
    5列追加 (派生)高齢化率 = 65 歳以上人口 (A1303) / 総人口 (A1101)最大 = 秋田県 (39.1%), 最小 = 東京都 (22.8%)15 秒
    6地方コード付与マージで地方ラベル付加未マッチ = 0、 地方の都道府県数の和 = 4760 秒
    7グループ化地方別人口合計グループ合計の総和 = 全 47 県合計と一致20 秒
    8読み込みExcel テーブル / Power BI モデルへ行数・列数がプレビューと一致10 秒

    合計 2 分強で SSDSE-B-2026 の典型的な前処理が一通り完了する。 これを毎月手動でやると 5-10 分かかるところを、 Power Query は クリック 1 つでリフレッシュ できる。 年 12 回の作業を自動化すると、 年間 1-2 時間の工数削減になる。

    🗺 学習ロードマップ — 30 日で Power Query を業務に持ち込む

    Power Query を「学んだことがある」から「業務で使えている」に引き上げるには、 30 日の集中演習が現実的。 SSDSE-B-2026 を 1 つの軸に据えると、 同じデータで段階的に難度を上げられる。

    期間目標具体的タスク (SSDSE-B-2026)
    1-3 日GUI 操作の基本CSV 読込 → 型変換 → フィルタ → Excel テーブル出力
    4-7 日グループ化と集計地方ブロック付与 → 地方別人口・診療所数 合計
    8-12 日ピボットと結合年 × 県のクロス表、 地方コード対応表との結合
    13-18 日M 言語入門詳細エディタで let / in を読み書き、 ステップ名修正
    19-23 日カスタム関数と再利用「数値を千単位に変換」を関数化、 全列に適用
    24-28 日パラメータと自動化年パラメータで対象年を切替、 OneDrive にスケジュール更新
    29-30 日Power BI 連携Excel → .pbix にコピー、 ダッシュボード化

    この 30 日プランを完走すると、 SSDSE-B-2026 を題材にした「再現可能な分析パイプライン」を 1 人で組めるようになる。 そこから先は社内データに置き換えるだけで、 即戦力に転じる。 「同じデータを 30 日触る」の継続性が、 ETL スキル習得の最短ルートと言える。

    power query Privacy Levels 認証情報の管理 機密データの匿名化 監査ログ スケーラビリティ OneLake 統合

    🔗 隣接手法への橋渡し

    Power Query は Excel・Power BI のデータ取り込み & 前処理エンジンで、 ETL・データクレンジング・自動更新の中核。

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

    🌳 手法選択フロー

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

    1. 繰り返す作業か、 1 回だけか
      毎月同じ整形をするなら、 手順が記録される Power Query が向く。 1 回で終わるなら、 手作業や単発のスクリプトのほうが速い。
    2. 誰が保守するか
      Excel 上で GUI で組めるので、 プログラミングをしない人でも引き継げる。 一方、 差分の追跡やレビューはコードほどやりやすくない。
    3. データ量はどれくらいか
      数十万行を超えると動作が重くなる。 その規模になったら、 データベース側で集計してから取り込む形に変える。
    4. 文字コードと型を指定したか
      SSDSE のような cp932 の CSV は、 読み込み時に文字コードを指定しないと文字化けする。 地域コードは文字列として読み、 先頭 0 が消えないようにする。

    Power Query の価値は「同じ整形を再実行できる」こと。 手作業の置き換えとしては強いが、 規模が大きくなったら別の道具に移る前提で使う。

    🔎 もう一歩 — 「クエリ畳み込み」で速さが決まる

    🎯 直感 — GUIのクリックは裏で M コードに翻訳されている

    Power Query の一番の勘所は、画面のクリック操作が 1 つずつ M 言語のコードに翻訳されているという点だ。 「列を削除」ボタンを押すと Table.RemoveColumns(...) が 1 行追記され、「型変換」を選ぶと Table.TransformColumnTypes(...) が積まれる。 GUI 操作と生成コードが完全に 1 対 1 対応しているので、詰まったら「詳細エディタ」で M コードを直接見れば全ステップの実体が読める。 このページ本文で扱った M コード(Csv.DocumentPromoteHeadersTransformColumnTypesSelectRows)は、まさに 4 回のクリックの記録そのものだ。

    ⚠️ 落とし穴(重要)— Query Folding が「途切れる」と巨大データで激遅になる

    Power Query が DB(SQL Server など)に接続しているとき、フィルタや列削除といった変換はソース側の SQL に変換してデータベースに押し戻される。 これを Query Folding(クエリの畳み込み) と呼ぶ。 畳み込みが効いていれば、必要な行・列だけが手元に届く。 ところが Table.Buffer・カスタム M 関数・インデックス列追加など畳み込みできない操作を途中に挟むと、その地点で folding が途切れ、以降は全件をローカルに引いてから処理する。 これが「なぜか激遅」の典型原因だ。

    🚀 発展 — インクリメンタル更新と Fabric データフロー

    Query Folding が効いていると、インクリメンタル更新(増分更新)が使える。 更新のたびに全期間を取り直すのではなく、変更のあった期間だけを DB から取得する仕組みだ。 SSDSE のように「毎年 1 年分(47 行)が追加される」時系列(現在 12 年分 564 行)では、増分更新なら追加分だけを取り込めばよく、履歴の再取得を避けられる。 この考え方は Power BI / Microsoft Fabric のデータフローへと発展し、複数レポートで同じ整形済みテーブルを共有する基盤になる。 GUI で書いた M クエリが、そのままクラウドの共有 ETL 資産に育つ流れだ。

    🔗 関連ページ