国勢調査をもとにした人口推移のCSVを使います。
このデータの中には、都道府県別の人口推移があるので、pandasで解析してみましょう。
とりあえず
という目的でやってみましょう。
データは政府統計の総合窓口(e-Stat)からもらってきました(エンコードが SHIFT-JIS だったようなので、指定して読み込みます)。
手順としては、次のような感じで進めます。
import pandas as pd
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
# 日本語フォントを使いたいので、 font.family を変更する(OS などで異なるので注意)
plt.rcParams['font.family'] = "Hiragino Sans"
# 最初の5行を出力
with open("c01.csv", "r", encoding="shift-jis") as fp:
for line in fp.readlines()[:5]:
print(line.strip())
pandasだとcsvを一行で読み込むことが出来ます(エンコードは適当に探す)
# 一行でcsvファイルをDataFrameに変換できる
df = pd.read_csv("c01.csv", encoding="shift-jis", skipfooter=2, engine="python")
df = df.rename(columns={"人口(総数)": "全人口", "人口(男)": "男", "人口(女)": "女"})
# 最初の5行
df.head()
# 最後の5行
df.tail()
# dfのSeriesを確認
df.columns
# 各Seriesのdtypeの確認
df.dtypes
# 人口を数値データに変換
for col in ["全人口", "男", "女"]:
df[col] = pd.to_numeric(df[col], errors="coerce")
pd.to_numeric?をみると
Signature: pd.to_numeric(arg, errors='raise')
errors : {'ignore', 'raise', 'coerce'}, default 'raise'
- If 'raise', then invalid parsing will raise an exception
- If 'coerce', then invalid parsing will be set as NaN
- If 'ignore', then invalid parsing will return the input
errors="coerce"とキーワード引数を与えてやれば、キャストできないものを欠損値として置き換えてくれるそうです。
デフォルトではエラーを吐き出すという設定になっていますね。
df.dtypes
# 組み込み関数のset()と似た働き
df["都道府県名"].unique()
都道府県別の時系列を見てみたいので、「全国」と最後の2つは取り除きましょう。
DataFrame.dropはindexが引数に一致している行を削除したDataFrameを返す関数です。
# 都道府県の行だけを抽出する
df = df[df["都道府県名"].isin(df["都道府県名"].unique()[1:-2])]
さて、解析のための準備が整いました。
都道府県名をkeyにしてgroupbyし、その勾配を求める自作関数を作れば良さそうです。
indexはこれから時系列として扱うので西暦に変更しておきます。
df.index = df['西暦(年)']
試しに各都道府県の人口推移をプロットしてみます。
df.groupby("都道府県名")["全人口"].plot(x="西暦")
plt.show()
# Seriesを受け取って、勾配を返す関数
def calc_slope(sr):
# 欠損値を取り除く
sr = sr.dropna()
# x軸として年を取る
x = sr.index.values
# Green関数(直線なのでパラメータ2つ)
G = np.vstack((x, np.ones_like(x))).T
d = sr.values
# 直線のパラメータ
params = np.linalg.pinv(G) @ d
# 勾配のみを返す
return params[0]
increase_rate = df.groupby("都道府県名")[["全人口", "男", "女"]].agg(calc_slope)
increase_rate.head()
ようやく、都道府県ごと、ついでに性別別の人口増加速度が求まりました。
fig, ax = plt.subplots(figsize=(6, 10), dpi=200)
increase_rate.sort_values("全人口").plot.barh(ax=ax)
plt.title("都道府県別平均人口増加速度(大正9年~平成27年)", fontsize=15)
plt.xlabel("平均人口増加速度(人/年)", fontsize=20)
plt.tight_layout()
plt.show()
完成です。
今回は都道府県別を調べましたが、データさえあれば、(コードをほとんど変えずに)市町村でもできることが分かってもらえると思います。
このようにpandasには汎用性の高い機能がたくさんあり、それらを組み合わせる技術が問われていくのだろうと思います。
参考にしてほしい本として「Pythonによるデータ分析入門(O'REILLY)」があります。
これはPandasを作った人の本であり、(当然ながら)Pandasについてとても詳細に書かれています。
読んだら当然理解できるはずですが、読まなくてもPandasを使いながらググったり、ドキュメントを読んでいると自然と必要な機能は分かってくると思います。