統計分析お題：県ごとの人口密度の変遷を、折れ線グラフで作成して。

データ分析の色々が知りたいと思っても、初学者にいい感じのお題が見つからなかったので、

# 統計分析お題「県ごとの人口密度の変遷を、折れ線グラフで作成して。」

と偉い人に言われたと仮定して、以下のように計画を立てました。

# 統計計画
 - 都道府県別、年別の人口推移データを取得
 - 都道府県別面積一覧を取得
 - 都道府県別、年別に人口密度を算出
     - 人口DF、面積DFを読み込み
     - 都道府県ごとにループ
         - 都道府県番号で人口DFのレコードを抽出
         - 人口数のすべての列に、面積を割って人口密度を算出
         - 新しいデータセットに追加
 - 人口密度で折れ線グラフを作成

# やってみる
## 都道府県別、年別の人口推移データを取得
データは以下から取得。
https://data.e-gov.go.jp/data/ja/dataset/mhlw_20201124_0048
ここから「4_年次・都道府県・性別人口_(1) 総数」のCSVデータをダウンロード

ヘッダフッタを削除して、全国版データも削除。
都道府県名の列に番号が混ざっているので、これを分離。

population_japan_pref.csvとして保存

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517776/f617663e-e664-8005-96cf-29c7d2e8c5e6.png)

ここで、年次が５年おきだったり、２０１４年以降は１年ごとだったりすることに気づく。とりあえず進める。

また、後々つまずくことになるので今のうちに、沖縄県の複数の年が「・・・」という文字列になっているので、０に置換。

## 都道府県別面積一覧を取得
データは以下から取得。
https://www.gsi.go.jp/KOKUJYOHO/OLD-MENCHO-title.htm
ここから「　令和元年7月以降（令和5年7月まで)[CSV:413KB]」をダウンロード

市区町村のデータはいらないので削除。
都道府県ごとにエリアコードが割り当てられているこれを先に整えたデータの
都道府県番号とそろえるために、エリアコードを1000で割っておく。
最終的に以下のようになる。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517776/e8ab7149-4e71-caf0-3937-b4a030ce123d.png)



## 都道府県別、年別に人口密度を算出

Jupyter Notebookファイルを新規に作成。
CSV読み込み

```popuration_density.py
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')

```

「都道府県別面積一覧」から１つずつレコードを取り出し、都道府県番号(area_code)と合致した「都道府県別、年別の人口推移」のレコードの、各年の人口を面積で割って人口密度にする。これを全都道府県分ループ。

人口密度の計算は、applyメソッドを使用。

※こちらの記事を参照しました。
https://qiita.com/hisato-kawaji/items/0c66969343a196a65cee

ここではまったポイントが一つ。
データフレームから１つのレコードを取り出して、それに対してapplyすると、そのデータはシリーズになる模様。
※こちらの記事にまさにそのことと対処法が書かれていました。感謝、、
https://qiita.com/ryamamoto0406/items/2f068a9904731d3f0df1

```popuration_density.py
# 都道府県ごとにループ
# 都道府県ごとにループ
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)
```

こうすると以下のように都道府県別、年代別に人口密度が求まる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517776/f3710e71-deff-fa2e-14f5-14168d5b9813.png)

※以下の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:

欲しかったデータに変換できたので、折れ線グラフにプロット。

```popuration_density.py
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()
```

日本語フォントが文字化けしたりするのに手こずって、結果上記のようなコードに。
結果、以下のようなグラフを得た。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517776/ed5afb6c-88b1-1f9f-4187-e19c827fa4fd.png)

# 終わりに

なんとか人口密度を都道府県別、年経過ごとにまとめることができました。（ ~~これエクセルだと数分でできるやつ、、~~ ）
また判例がとんでもないことになってしまったので、今後は上位５位とかフィルタして、欲しいデータのみグラフ化するなどしたいです。（てかそもそもmatplotlibの使い方から）