平均寿命の箱ひげ図をPandasでデータラングリング

ameblo.jp

箱ひげ図の書き方がわからなかったので参考にさせていただきました。

blog.goo.ne.jp

blog.goo.ne.jp

CSV

drive.google.com

プログラム

  • 散布図が合わない => 都道府県で散布図を描くと同じになりました
  • 特別区都道府県と市郡の重複を抽出して、区町村が””を抽出しています。※都道府県と市郡の重複の一番最初を取得したかったけどやりかたがわからなかった

imabari.hateblo.jp

!wget "https://www.mhlw.go.jp/toukei/saikin/hw/life/ckts15/dl/ckts15-06.xls" -O data.xls
import pandas as pd

dfs = []

for i in range(1, 13):
    df1_tmp = pd.read_excel("data.xls", sheet_name=f"統計表1-{i}", header=None, na_values=[0, "…"])

    df2_tmp = df1_tmp.loc[
        df1_tmp.notnull().sum(axis=1) > 2, df1_tmp.notnull().sum() > 2
    ].copy()

    # 列数取得
    _, col = df2_tmp.shape

    for n in range(0, col, 4):
        df3_tmp = df2_tmp.iloc[:, n : n + 4].copy()

        df3_tmp.columns = ["市郡", "区町村", "男", "女"]

        df3_tmp["区町村"] = df3_tmp["区町村"].str.strip()
        df3_tmp["区町村"] = df3_tmp["区町村"].mask(df3_tmp["区町村"] == "")

        df3_tmp.dropna(how="all", inplace=True)

        df3_tmp["区町村"].fillna("", inplace=True)

        dfs.append(df3_tmp)

# 結合
df = pd.concat(dfs)

# タイトル行削除
df1 = df[df['市郡'] != "市区町村"].copy()

df1["男"] = df1["男"].astype(float)
df1["女"] = df1["女"].astype(float)

# 都道府県を抽出、都道府県の列作成
df1["都道府県"] = df1["市郡"].where(~df1["市郡"].str.startswith(" "))
df1["都道府県"].fillna(method="ffill", inplace=True)

# 集計用の列作成
df1["集計"] = 1

# 都道府県は0
df1.loc[~df1["市郡"].str.startswith(" "), "集計"] = 0

# 空白を除去
df1["市郡"] = df1["市郡"].str.strip()

# 特別区は-1
df1.loc[(df1.duplicated(subset=["都道府県", "市郡"], keep=False)) & (df1["区町村"] == ""), "集計"] = -1

# 全国は-1
df1.loc[df1["市郡"] == "全国", "集計"] = -1

# 東京都区部は-1
df1.loc[df1["市郡"] == "東京都区部", "集計"] = -1

# 確認
df1[df1["集計"] == -1]

df2 = df1[df1["集計"] > 0].copy().drop("集計", axis=1).reset_index(drop=True)

df2 = df2.loc[:, ["都道府県", "市郡", "区町村", "男", "女"]]

df2.to_csv("data.csv")

グラフ

!pip install japanize-matplotlib

import seaborn as sns
import japanize_matplotlib
import matplotlib.pyplot as plt

df3 = df2.loc[:, ["都道府県", "男", "女"]]

df3
# 男
plt.figure(figsize=(9, 18))
order = df3.groupby("都道府県")["男"].mean().sort_values()
sns.boxplot(x="男", y="都道府県", data=df3, order=order.index, whis="range",showmeans=True)
plt.savefig('figure_m.png')

f:id:imabari_ehime:20200124232654p:plain

# 女
plt.figure(figsize=(9, 18))
order = df3.groupby("都道府県")["女"].mean().sort_values()
sns.boxplot(x="女", y="都道府県", data=df3, order=order.index, whis="range",showmeans=True)
plt.savefig('figure_f.png')

f:id:imabari_ehime:20200124232720p:plain

df4 = df3.groupby("都道府県").mean()

df4.plot.scatter(x="男", y="女", grid=True, xlim=(78.5, 82), ylim=(85.5, 88), figsize=(8, 6))
plt.savefig("scatter.png")

f:id:imabari_ehime:20200124232730p:plain

都道府県のデータで散布図書いたら同じグラフかけた

df5 = df1.loc[df1["集計"] == 0, ["都道府県", "男", "女"]].set_index("都道府県")

df5.plot.scatter(x="男", y="女", grid=True, xlim=(78.5, 82), ylim=(85.5, 88), figsize=(8, 6))
plt.savefig("scatter2.png")

f:id:imabari_ehime:20200125104237p:plain