データ分析の色々が知りたいと思っても、初学者にいい感じのお題が見つからなかったので、
統計分析お題「県ごとの人口密度の変遷を、折れ線グラフで作成して。」
と偉い人に言われたと仮定して、以下のように計画を立てました。
統計計画
- 都道府県別、年別の人口推移データを取得
- 都道府県別面積一覧を取得
- 都道府県別、年別に人口密度を算出
- 人口DF、面積DFを読み込み
- 都道府県ごとにループ
- 都道府県番号で人口DFのレコードを抽出
- 人口数のすべての列に、面積を割って人口密度を算出
- 新しいデータセットに追加
- 人口密度で折れ線グラフを作成
やってみる
都道府県別、年別の人口推移データを取得
データは以下から取得。
https://data.e-gov.go.jp/data/ja/dataset/mhlw_20201124_0048
ここから「4_年次・都道府県・性別人口_(1) 総数」のCSVデータをダウンロード
ヘッダフッタを削除して、全国版データも削除。
都道府県名の列に番号が混ざっているので、これを分離。
population_japan_pref.csvとして保存
ここで、年次が5年おきだったり、2014年以降は1年ごとだったりすることに気づく。とりあえず進める。
また、後々つまずくことになるので今のうちに、沖縄県の複数の年が「・・・」という文字列になっているので、0に置換。
都道府県別面積一覧を取得
データは以下から取得。
https://www.gsi.go.jp/KOKUJYOHO/OLD-MENCHO-title.htm
ここから「 令和元年7月以降(令和5年7月まで)[CSV:413KB]」をダウンロード
市区町村のデータはいらないので削除。
都道府県ごとにエリアコードが割り当てられているこれを先に整えたデータの
都道府県番号とそろえるために、エリアコードを1000で割っておく。
最終的に以下のようになる。
都道府県別、年別に人口密度を算出
Jupyter Notebookファイルを新規に作成。
CSV読み込み
import pandas as pd
#CSVファイル読み込み
df_area= pd.read_csv('../data/area_japan_pref.csv')
df_population= pd.read_csv('../data/population_japan_pref.csv')
「都道府県別面積一覧」から1つずつレコードを取り出し、都道府県番号(area_code)と合致した「都道府県別、年別の人口推移」のレコードの、各年の人口を面積で割って人口密度にする。これを全都道府県分ループ。
人口密度の計算は、applyメソッドを使用。
※こちらの記事を参照しました。
https://qiita.com/hisato-kawaji/items/0c66969343a196a65cee
ここではまったポイントが一つ。
データフレームから1つのレコードを取り出して、それに対してapplyすると、そのデータはシリーズになる模様。
※こちらの記事にまさにそのことと対処法が書かれていました。感謝、、
https://qiita.com/ryamamoto0406/items/2f068a9904731d3f0df1
# 都道府県ごとにループ
# 都道府県ごとにループ
df_pop_density = pd.DataFrame()
for column_name,item in df_area.iterrows():
area_code = item[0]
pref_name = item[1]
population = item[2]
# 都道府県番号で人口DFのレコードを抽出
df_population_eachrow = df_population[df_population['area_code'] == area_code]
# 面積を各列の人口にかけるためのapply用関数を定義
def population_density(population,area):
if int(population) == 0:
ret = 0
else:
ret = float(population) / float(area)
return ret
# applyすると結果はシリーズになる。
sr_temp = df_population_eachrow.iloc[[0],2:].apply(population_density,args=(population,))
# https://qiita.com/ryamamoto0406/items/2f068a9904731d3f0df1
# 空のデータフレームに列とデータを追加しようとしても列のみ追加されてデータが追加されないので、
# シリーズをデータフレームに変換して格納する。
df_temp = pd.DataFrame()
df_temp = pd.concat(
[
df_temp, pd.DataFrame([sr_temp],index=[str(pref_name)])
], ignore_index=False, axis=1)
df_pop_density = pd.concat([df_pop_density, df_temp], ignore_index=False)
print(df_pop_density)
こうすると以下のように都道府県別、年代別に人口密度が求まる。
※以下のWarningが出るけどこれを調べるのはまた次の機会に、、
FutureWarning: Calling int on a single element Series is deprecated and will raise a TypeError in the future. Use int(ser.iloc[0]) instead
if int(population) == 0:
欲しかったデータに変換できたので、折れ線グラフにプロット。
import matplotlib
import matplotlib.pyplot as plt
#fonts = set([f.name for f in plt.font_manager.fontManager.ttflist])
#print(fonts)
# MS Gothicが使える
matplotlib.rcParams['font.family'] = 'MS Gothic'
#plt.show()
df_pop_density.T.plot()
日本語フォントが文字化けしたりするのに手こずって、結果上記のようなコードに。
結果、以下のようなグラフを得た。
終わりに
なんとか人口密度を都道府県別、年経過ごとにまとめることができました。( これエクセルだと数分でできるやつ、、 )
また判例がとんでもないことになってしまったので、今後は上位5位とかフィルタして、欲しいデータのみグラフ化するなどしたいです。(てかそもそもmatplotlibの使い方から)