Pandasでe-Statの年齢・男女別人口推移データ

EDA Salon 第6回 - 日本の統計データ(e-Stat)のデータラングリング大会

EDA Salon 第6回 - 日本の統計データ(e-Stat)のデータラングリング大会 年齢・男女別人口推移データ(難易度:普通)

www.e-stat.go.jp

exploratory.io

exploratory.io

相違

Pandasで解いてみたのですが統計の合計が合わない

小数点以下が省略されているため合計が合わないようです

ja.wikipedia.org

f:id:imabari_ehime:20200115133451p:plain

drive.google.com

  • data.csv 抽出したデータ
  • data1.csv 抽出したデータから再集計

全部

抽出

import pandas as pd

df = pd.read_excel("https://www.e-stat.go.jp/stat-search/file-download?statInfId=000013168604&fileKind=0", header=None, skiprows=6)

df.head(20)

# 英語の行削除
df.drop(df.index[4], inplace=True)

# 英語の列削除
df.drop(df.columns[1], axis=1, inplace=True)

#df.replace("[a-zA-Z]", "", regex=True, inplace=True)
#df.mask(df == "", inplace=True)

# 年の「1)」を除去
df.iloc[0,:].replace("1\)", "", regex=True, inplace=True)

# 空白文字を除去
df.replace(r"\s", "", regex=True, inplace=True)

# 年の平成を除去
df.iloc[0,:].replace(r"平成(\d{2})年", "", regex=True, inplace=True)

# 年の欠損値を前の値で補完
df.iloc[0,:].fillna(method="ffill", inplace=True)

# 年齢の数字以外を除去
df.iloc[:,0].replace(r"歳(以上)?$", "", regex=True, inplace=True)

# タイトル補完
df.iloc[0, 0] = "年"
df.iloc[2, 0] = "性別"

# データ以外を行・列除去
df1 = df.loc[df.notnull().sum(axis=1) > 2, df.notnull().sum() > 2].copy()

# 欠損値を0で補間
df1.fillna(0, inplace=True)

df1

df1.T.to_csv("data.csv", encoding="utf_8_sig", index=False, header=False)

再集計

df2 = pd.read_csv("data.csv", index_col=[0,1], header=0)
df2.head(10)

df2a =  df2["総数"] - df2.loc[:, "0":"100"].sum(axis=1)

df2b = df2a.reset_index()

df2b.rename(columns={0:"差"}, inplace=True)

df2b.pivot_table(index="年", columns="性別", values="差")

df3 = pd.read_csv("data.csv", index_col=None, header=0)
df3.head(10)

df3.drop("総数", axis=1, inplace=True)
df3.head()

df4 = df3.melt(id_vars=["年", "性別"], var_name="年齢", value_name="人数")
df4.head(10)

pv4 = df4.pivot_table(index="年", columns="性別", values="人数", aggfunc="sum")

pv4["集計"] = pv4["男"] + pv4["女"]

pv4["差"] = pv4["男女計"] -  pv4["集計"]

pv4

df4["年齢"] = df4["年齢"].astype(int)
pv5 = df4.pivot_table(index=["年", "年齢"], columns="性別", values="人数", aggfunc="sum")

pv5["男女計"] = pv5["男"] + pv5["女"]

pv5.head(10)

pv = pv5.stack().reset_index().rename(columns={0:"人数"})

pv1 = pv.pivot_table(index=["年", "性別"], columns="年齢", values="人数")

pv1.index

new_idx = pd.MultiIndex.from_product([[2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015], ["男女計", "男", "女"]], names=pv1.index.names)
pv2 = pv1.reindex(new_idx)

new_idx = pd.MultiIndex.from_product([range(2000,2016), ["男女計", "男", "女"]], names=pv1.index.names)
pv2 = pv1.reindex(new_idx)

pv2["総数"] = pv2.sum(axis=1)

name = ["総数"] + list(range(101))

pv3 = pv2.loc[:, name]

pv3.to_csv("data1.csv", encoding="utf_8_sig")

Pandas

import pandas as pd

df = pd.read_excel("https://www.e-stat.go.jp/stat-search/file-download?statInfId=000013168604&fileKind=0", header=None, skiprows=6)

df.head(20)

# 英語の行削除
df.drop(df.index[4], inplace=True)

# 英語の列削除
df.drop(df.columns[1], axis=1, inplace=True)

# 年の「1)」を除去
df.iloc[0,:].replace("1\)", "", regex=True, inplace=True)

# 空白文字を除去
df.replace(r"\s", "", regex=True, inplace=True)

# 年の平成を除去
df.iloc[0,:].replace(r"平成(\d{2})年", "", regex=True, inplace=True)

# 年の欠損値を前の値で補完
df.iloc[0,:].fillna(method="ffill", inplace=True)

# 年齢の数字以外を除去
df.iloc[:,0].replace(r"歳(以上)?$", "", regex=True, inplace=True)

# タイトル補完
df.iloc[0, 0] = "年"
df.iloc[2, 0] = "性別"

# データ以外を行・列除去
df1 = df.loc[df.notnull().sum(axis=1) > 2, df.notnull().sum() > 2].copy()

# 欠損値を0で補間
df1.fillna(0, inplace=True)

# CSVに保存
df1.T.to_csv("data.csv", encoding="utf_8_sig", index=False, header=False)

df1

総数

df2 = pd.read_csv("data.csv", index_col=[0,1], header=0)
df2.head(10)

df2["総数"] - df2.loc[:, "0":"100"].sum(axis=1)
男女計
2000 0 -3 -4
2001 -1 1 -1
2002 2 -2 1
2003 -3 2 -2
2004 -2 2 -2
2005 2 4 2
2006 2 0 4
2007 3 2 -2
2008 -1 1 -2
2009 -2 -1 1
2010 8 4 0
2011 0 2 1
2012 1 1 3
2013 3 -2 0
2014 1 -1 5
2015 0 1 1

男女の計

df3 = pd.read_csv("data.csv", index_col=None, header=0)
df3.head(10)

df3.drop("総数", axis=1, inplace=True)
df3.head()

df4 = df3.melt(id_vars=["年", "性別"], var_name="年齢", value_name="人数")
df4.head(10)

pv4 = df4.pivot_table(index="年", columns="性別", values="人数", aggfunc="sum")

pv4["差"] = pv4["男女計"] -  pv4["男"] -  pv4["女"]
男女計
2000 62111 64818 126930 1
2001 62245 65046 127292 1
2002 62250 65185 127434 -1
2003 62307 65313 127621 1
2004 62297 65390 127689 2
2005 62347 65415 127766 4
2006 62328 65440 127766 -2
2007 62307 65459 127773 7
2008 62252 65440 127694 2
2009 62132 65381 127509 -4
2010 62320 65726 128057 11
2011 62184 65613 127798 1
2012 62028 65485 127512 -1
2013 61906 65390 127298 2
2014 61800 65283 127078 -5
2015 61842 65252 127094 0

年・年齢

df4["年齢"] = df4["年齢"].astype(int)
pv5 = df4.pivot_table(index=["年", "年齢"], columns="性別", values="人数", aggfunc="sum")

pv5["集計"] = pv5["男"] + pv5["女"]
pv5["差"] = pv5["男女計"] -  pv5["集計"]