出生性比

プロット

e-Statにある2020年の人口動態調査 / 人口動態統計 確定数 出生および厚労省の人口動態調査にある「人口動態統計(確定数)の概況」(最新のものは「人口動態統計月報年計(概数)の概況」)から、出生性比(出生数の男/女の比)をプロットする:

日本の出生性比の推移

1906年,1966年のピークは「ひのえうま」である。

ついでに合計特殊出生率もプロットする:

日本の合計特殊出生率の推移

詳細

e-Statの人口動態調査 / 人口動態統計 確定数 出生のCSVファイルの先頭部分は次のようになっている。文字コードはShift JIS,行末はCRLFである。

令和2年,人口動態統計,,
上巻 出生  第4.1表 年次別にみた出生数・出生率(人口千対)・出生性比及び合計特殊出生率

注 :1)1944年(昭和19年)〜1946年(昭和21年)は戦災による資料喪失等資料不備のため省略した。1947年(昭和22年)〜1972年(昭和47年)は沖縄県を含まない。
   2)1926年(昭和元年)・1930年(昭和5年)・1935年(昭和10年)の出生数の総数には、男女不詳が各1が含まれている。
   3)率算出に用いた分母人口は日本人人口である。
   4)2004・2006・2009〜2017年(平成16・18・21〜29年)の都道府県からの報告漏れ(2019年3月29日公表)による再集計を行ったことにより、
     2017年(平成29年)以前の報告書とは数値が一致しない箇所がある。
資料:国立社会保障・人口問題研究所「人口統計資料集」、厚生労働省「人口動態統計」
, 出生数,,, 出生率, 出 生,合計特殊
, 総 数,  男,  女,, 性 比,出 生 率
1899,1386981,713442,673539,32.0,105.9,…
1900,1420534,727916,692618,32.4,105.1,…
(中略)
2000,1190547,612148,578399,9.5,105.8,1.36
2001 ,1170662,600918,569744,9.3,105.5,1.33
2002,1153855,592840,561015,9.2,105.7,1.32
(後略)

最初の9行はメタ情報,次の2行は列見出しを2行に分けてスペースで整形したものである。本来のCSVにするためには,メタ情報を削除あるいはコメントアウト(頭に # を付けるなど)して,ヘッダ行を次のようにすればよい:

年,出生数_総数,出生数_男,出生数_女,出生率,出生性比,合計特殊出生率

さらによく見ると2001年に全角空白が紛れ込んでいる。最初これに気づかなかったので「年」がすべて文字列扱いになってしまった(RやExcelはこの全角空白を読み飛ばすようだ)。ここでは下記のように sep="\s*," で読み飛ばすことにした。

import pandas as pd

df = pd.read_csv("mb010000.csv", encoding="cp932", skiprows=11,
                 na_values="…", keep_default_na=False, sep="\s*,",
                 names=["年", "出生数_総数", "出生数_男", "出生数_女",
                        "出生率", "出生性比", "合計特殊出生率"])
df1 = df[["年", "出生数_男", "出生数_女", "合計特殊出生率"]]
df1.to_csv("births.csv", index=False, encoding="utf_8_sig", lineterminator="\r\n")

書き出されたCSVファイルに1944〜1946年の欠落部分を書き加え、2021年以上のデータは厚労省の人口動態調査にある「人口動態統計(確定数)の概況」(最新のものは「人口動態統計月報年計(概数)の概況」)から拾って書き加えたものを births.csv として置いておく。

これを読んで出生性比をプロットするには,次のようにすればよい。

import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv("https://okumuralab.org/~okumura/python/data/births.csv")
plt.figure(figsize=(14, 4))
plt.plot(df["年"], df["出生数_男"] / df["出生数_女"], "o-")
plt.grid()

合計特殊出生率も同様に描く:

plt.plot(df["年"], df["合計特殊出生率"], "o-")
plt.grid()

直近の性比の信頼区間はどれくらいか。

from scipy import stats

m = int(df["出生数_男"].values[-1])
f = int(df["出生数_女"].values[-1])
print(m / f)
ci = stats.binomtest(m, m+f).proportion_ci()
print([ci.low / (1 - ci.low), ci.high / (1 - ci.high)])

95%信頼区間はだいたい ±0.005 ほどである。

性比については Is sex at birth a biological coin toss? Insights from a longitudinal and GWAS analysis のような話もあり、いろいろおもしろい。


Last modified: