【Pythonデータサイエンス入門,matplotlib】統計を利用して日本の人口について見てみよう③

環境

macOS Sierra 10.12.6
ターミナル
Anaconda
Python 3.6.4

Anacondaをインストールすればデータサイエンスに必要なライブラリが使えるので、
ぜひインストールしましょう。

Anacondaのインストール手順についてはこちら
MacにAnacondaをインストールする

matplotlibとは

データ可視化ツールのうちのひとつです。
データ分析を行う際に使います。

たった数行のPythonコードで簡単な棒グラフ、折れ線グラフ、散布図などを表示することができます。
matplotlib→https://matplotlib.org/
参考:matplotlibで日本語対応(文字化け解決),Mac

当記事で使うデータ

総務省統計局の人口推計のデータを参照します。
転載について記載するよう書いてあったので記載しておきます。

「人口推計」(総務省統計局)(http://www.stat.go.jp/data/jinsui/pdf/201802.pdf)(2018年3月8日に利用)

さまざまな値を求めてみよう:平均値・中央値・分位数

前回:【Pythonデータサイエンス入門,matplotlib】統計を利用して日本の人口について見てみよう②

さて、前回の続きで、男性の人口でさまざまな値を求めてみましょう。

まず、元となるデータはageリストとpopulationリストですね。

# 人口推計でもそうしているように、年齢を5歳刻みで1セットとする。
# ageというリストで年齢要素を管理する。
age = ["0-4歳", "5-9歳", "10-14歳", "15-19歳", "20-24歳", "25-29歳", "30-34歳",
       "35-39歳", "40-44歳", "45-49歳", "50-54歳", "55-59歳", "60-64歳",
       "65-69歳", "70-74歳", "75-79歳", "80-84歳", "85-89歳", "90-94歳",
       "95-99歳", "100歳以上"]
 
# 男性の日本人人口の値をpopulationというリストに格納。
# 単位が千人というのはそのまま採用、ageリストの順番と対応する。
# たとえば0-4歳は2478で、それぞれage[0],population[0]で対応しているということ。
population = [2478, 2662, 2760, 3033, 3042, 3067, 3512, 3916, 4727, 4705,
              4036, 3742, 3832, 4798, 3586, 2992, 2143, 1166, 413, 70, 9]

populationの最大値・最小値を求める

前回、最大値は求めましたが、おさらいの意味もこめて最小値とともに求めてみましょう。

>>> age = ["0-4歳", "5-9歳", "10-14歳", "15-19歳", "20-24歳", "25-29歳", "30-34歳",
...        "35-39歳", "40-44歳", "45-49歳", "50-54歳", "55-59歳", "60-64歳",
...        "65-69歳", "70-74歳", "75-79歳", "80-84歳", "85-89歳", "90-94歳",
...        "95-99歳", "100歳以上"]
>>> population = [2478, 2662, 2760, 3033, 3042, 3067, 3512, 3916, 4727, 4705,
...               4036, 3742, 3832, 4798, 3586, 2992, 2143, 1166, 413, 70, 9]
>>> age[population.index(max(population))]  # 前回と同じ
'65-69歳'
>>> age[population.index(min(population))]  # min()を使う。当然100歳以上が一番少ない
'100歳以上'

2番目に大きい、2番めに小さいを求める

>>> age = ["0-4歳", "5-9歳", "10-14歳", "15-19歳", "20-24歳", "25-29歳", "30-34歳",
...        "35-39歳", "40-44歳", "45-49歳", "50-54歳", "55-59歳", "60-64歳",
...        "65-69歳", "70-74歳", "75-79歳", "80-84歳", "85-89歳", "90-94歳",
...        "95-99歳", "100歳以上"]
>>> population = [2478, 2662, 2760, 3033, 3042, 3067, 3512, 3916, 4727, 4705,
...               4036, 3742, 3832, 4798, 3586, 2992, 2143, 1166, 413, 70, 9]

>>> sorted_values = sorted(population)  # 小さい順に並ぶ
>>> second_largest = sorted_values[-2]  # 小さい順に並んでるリストの後ろから2番目
>>> age[population.index(second_largest)]
'40-44歳'
>>> second_smallest = sorted_values[1]  # 第2位の少なさ
>>> age[population.index(second_smallest)]
'95-99歳'

平均値を求める

あまり有用なデータとは言えないかもしれませんが、populationリストの要素の平均値を調べてみます。

>>> sum(population) / len(population)
2889.9523809523807

sum()を使ってpopulationの要素を合計し、len()でpopulationのリストの長さを出しています。
平均値を求めるのは簡単ですね。

中央値を求める

平均値では、100歳以上や95-99歳の人も含まれています。
中央値は、データの大きさとして真ん中に位置するデータのことを指します。
データの個数が奇数個の場合はぴったり真ん中の値が存在することになるので、それが中央値となります(たとえば1,2,3,4,5という数の集まりの真ん中は3)。
データの個数が偶数個の場合は、真ん中に位置するデータ2つの平均値となります(たとえば1から6まである数なら3と4の平均、すなわち3.5が中央値)。

def median(v):  # 中央値を求める関数median(),vの中央値を求める
    n = len(v)
    sorted_v = sorted(v)
    midpoint = n // 2  # 整数の割り算。たとえば7 // 2は3となる

    if n % 2 == 1:  # 2で割った余りが1、すなわち奇数の時
        return sorted_v[midpoint]
    else:  # 偶数の時
        low = midpoint - 1
        high = midpoint
        return (sorted_v[low] + sorted_v[high]) / 2  # 真ん中2つの値の平均値

median.pyを編集したフォルダでPythonの対話型インタープリタを立ち上げて実行してみましょう。

>>> import median
>>> population = [2478, 2662, 2760, 3033, 3042, 3067, 3512, 3916, 4727, 4705,
...               4036, 3742, 3832, 4798, 3586, 2992, 2143, 1166, 413, 70, 9]
>>> median.median(population)  # medianモジュールのmedian()関数にpopulationという引数を渡して実行
3042

# 参考 populationリストは21個(奇数)要素がある。0番目から数えて10番目がそのまま中央値
>>> sorted(population)
[9, 70, 413, 1166, 2143, 2478, 2662, 2760, 2992, 3033, 3042, 3067, 3512, 3586, 3742, 3832, 3916, 4036, 4705, 4727, 4798]

では、3042はどの年齢層でしょうか。

>>> age = ["0-4歳", "5-9歳", "10-14歳", "15-19歳", "20-24歳", "25-29歳", "30-34歳",
...        "35-39歳", "40-44歳", "45-49歳", "50-54歳", "55-59歳", "60-64歳",
...        "65-69歳", "70-74歳", "75-79歳", "80-84歳", "85-89歳", "90-94歳",
...        "95-99歳", "100歳以上"]
>>> age[population.index(3042)]
'20-24歳'

分位数を求める

中央値を一般化したのが分位数です。
中央値は50%にあたる数で、分位数は特定のパーセンテージにある値がどれかを示します。

def quantile(x, p):
    p_index = int(p * len(x))
    return sorted(x)[p_index]
>>> import quantile
>>> age = ["0-4歳", "5-9歳", "10-14歳", "15-19歳", "20-24歳", "25-29歳", "30-34歳",
...        "35-39歳", "40-44歳", "45-49歳", "50-54歳", "55-59歳", "60-64歳",
...        "65-69歳", "70-74歳", "75-79歳", "80-84歳", "85-89歳", "90-94歳",
...        "95-99歳", "100歳以上"]
>>> population = [2478, 2662, 2760, 3033, 3042, 3067, 3512, 3916, 4727, 4705,
...               4036, 3742, 3832, 4798, 3586, 2992, 2143, 1166, 413, 70, 9]
>>> quantile.quantile(population, 0.5)
3042
>>> quantile.quantile(population, 0.8)
3916
>>> quantile.quantile(population, 0.1)
413
>>> age[population.index(quantile.quantile(population, 0.5))]  # 50%(=中央値)
'20-24歳'
>>> age[population.index(quantile.quantile(population, 0.8))]  # 80%
'35-39歳'
>>> age[population.index(quantile.quantile(population, 0.1))]  # 10%
'90-94歳'