K_DM Book
用語集
対象者 標準
対象者別の入口 →

対象者の設定はこのブラウザの中にだけ保存されます。

言語 JA

サンプルデータの取得と整形

01.2.1

サンプルデータの取得と整形

最終更新 2024-06-01 読了時間 3 分
まとめ
公開データの CSV は「1 行目がタイトル、2 行目が単位、マイナスが △」のように、そのまま read_csv しても数値として扱えない形で配られることが多いです。このページでは総務省「地方財政白書」の CSV を pd.read_csv(src, header=None) で読み込み、iloc[1] の行を set_axis でヘッダーに差し替え、「△」を「-」に置換してから pd.to_numeric(errors="coerce") で全列を数値にします。describe().T で桁違いや欠損を確かめたあと、to_csv(encoding="utf-8-sig") で soumu-gdp-clean.csv を書き出し、取得日や加工内容を辞書 metadata に残します。読み終えると、data/raw/ に元ファイル、data/processed/ に整形後ファイルを置く再現可能な取得・整形の流れが作れます。

直感 #

役所が公開する Excel や CSV は「人が読む表」として作られているので、タイトル行・単位行・結合セルの名残が混ざっていて、pandas が期待する「1 行目が列名、2 行目から数値」になっていません。整形とは、この人向けの表をプログラム向けの表に組み替える作業で、ヘッダーの差し替え・記号の置換・型変換の 3 手順でほぼ片付きます。その手順をスクリプトに残しておくと、白書が更新されたときも同じコードを再実行するだけで済みます。

使うデータとライセンス #

出典は総務省「地方財政白書」の公開資料(https://www.soumu.go.jp/menu_seisaku/hakusyo/chihou/)で、二次利用は可能ですが、出典明記と利用ルールへの同意が必要です。

Notebook / Python スクリプトで扱うときは、まずダウンロードした元ファイル(CSV・Excel)を data/raw/ に置き、次に整形後のファイルを data/processed/ に書き出し、最後にライセンス表記・入手先 URL を README か Notebook 冒頭に記載する、という運用にしておくと再現性のあるデータ基盤になります。


1. ダウンロードとヘッダー整形 #

次のコードは、入力と出力のフォルダを用意し、CSV をヘッダーなしの状態で読み込んで先頭 5 行を表示します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import pandas as pd
from pathlib import Path

RAW = Path("../data/raw")
PROCESSED = Path("../data/processed")
RAW.mkdir(parents=True, exist_ok=True)
PROCESSED.mkdir(parents=True, exist_ok=True)

src = RAW / "soumu-gdp.csv"
df_raw = pd.read_csv(src, header=None)
df_raw.head()

多くの公開資料は「1 行目=タイトル」「2 行目=単位」といった構成になっています。header=None で読み込んでから、必要な行をヘッダーに差し替えます。次のコードは 2 行目を列名に、3 行目以降をデータにして、マイナス記号を直します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
header = df_raw.iloc[1].ffill()
df = (
    df_raw
    .iloc[2:]                 # データ本体のみ
    .set_axis(header, axis=1) # ヘッダーに置き換え
    .rename(columns={"Unnamed: 0": "カテゴリ"})
    .replace("△", "-", regex=True)
    .replace("-", 0)
)
df.head()

Column 名の正規化 #

次のコードは、列名の前後の空白と全角括弧を揃えます。

1
2
3
4
5
6
7
df.columns = (
    df.columns
      .str.strip()
      .str.replace(" ", "")
      .str.replace("(", "(")
      .str.replace(")", ")")
)

2. 型の見直し・基本統計 #

次のコードは、「カテゴリ」以外の列をすべて数値に変換し、列ごとの件数・平均・標準偏差・最小・最大を確かめます。

1
2
3
4
5
6
7
8
9
numeric_cols = df.columns.drop(["カテゴリ"])
df[numeric_cols] = df[numeric_cols].apply(pd.to_numeric, errors="coerce")

profile = (
    df.describe()
      .T.loc[:, ["count", "mean", "std", "min", "max"]]
      .round(2)
)
profile.head()

3. 保存とメタデータ #

次のコードは、整形後の表を CSV に保存し、取得日や加工内容を辞書に記録します。

1
2
3
4
5
6
7
8
9
output = PROCESSED / "soumu-gdp-clean.csv"
df.to_csv(output, index=False, encoding="utf-8-sig")

metadata = {
    "source": "総務省 地方財政白書",
    "downloaded_at": "2024-05-30",
    "columns": df.columns.tolist(),
    "notes": "△ を - (マイナス) に置換。欠損は 0 に置換済み。"
}

整形後の CSV と一緒にメタデータ(取得日、加工内容、単位)を JSON で残しておくと、将来の再取得・差分チェックが容易になります。


4. Notebook での表示ユーティリティ(任意) #

次のコードは、見出し付きで DataFrame を表示する小さな関数を定義し、加工後の先頭 5 行を表示します。

1
2
3
4
5
6
7
8
from IPython.display import display, HTML

def show(df, title):
    display(HTML(f"<h3>{title}</h3>"))
    display(df)
    display(HTML("<hr>"))

show(df.head(), "加工後の先頭 5 行")

チェックリスト #

最初に確認したいのは、出典 URL と利用条件を Notebook / レポートに明記したかです。二つ目は整形プロセスをスクリプト化し、再実行しても同じ soumu-gdp-clean.csv になるかで、三つ目はヘッダー・単位のズレを修正し、全角括弧や空白を揃えて日本語列名も統一したかです。四つ目はオリジナル(data/raw/)と加工後(data/processed/)のどちらも保存し、ファイル名規約を決めたか、最後に欠損値・型変換のログを metadata として残したかを見ます。

このページで作成した soumu-gdp-clean.csv は、後続の pandas / SQL 例で利用します。