1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Posted at

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

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

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

統計計画

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

やってみる

都道府県別、年別の人口推移データを取得

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

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

population_japan_pref.csvとして保存

image.png

ここで、年次が5年おきだったり、2014年以降は1年ごとだったりすることに気づく。とりあえず進める。

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

都道府県別面積一覧を取得

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

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

image.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')

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

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

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

ここではまったポイントが一つ。
データフレームから1つのレコードを取り出して、それに対して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

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

終わりに

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

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?