いっかくのデータサイエンティストをいく

1からプログラミングとデータサイエンスを独習したい

【統計学】度数分布表をつくる(Python編)

前回はRで度数分布表とヒストグラムを実装しましたが、 今回はPythonで度数分布表を実装します。

上の書籍の第1章SECTION5に該当。

Pythonでの実装は、検索では度数分布表の関数が見つからなかったので自分で作ってみました。 とはいえ関数化はできていません。。。

データを確認する

前回と同様の データは0から200までの数字をランダムで100個発生させた下のようなものを使用します。

154,196,190,28,122,78,150,99,72,117,
73,195,3,62,190,125,7,63,182,56,
7,29,56,104,154,12,117,63,90,176,
101,168,47,99,69,124,55,173,115,71,
93,31,66,21,5,155,8,54,131,146,
54,160,10,59,140,103,40,23,125,35,
170,145,148,109,22,60,63,13,167,111,
125,78,97,130,118,140,29,156,146,94,
98,12,78,171,161,71,96,198,170,177,
145,5,197,186,15,95,30,162,165,108

まずはデータの読込と基本統計量の確認。

import pandas as pd

#データ読込
data = pd.Series([
        154,196,190,28,122,78,150,99,72,117,
        73,195,3,62,190,125,7,63,182,56,
        7,29,56,104,154,12,117,63,90,176,
        101,168,47,99,69,124,55,173,115,71,
        93,31,66,21,5,155,8,54,131,146,
        54,160,10,59,140,103,40,23,125,35,
        170,145,148,109,22,60,63,13,167,111,
        125,78,97,130,118,140,29,156,146,94,
        98,12,78,171,161,71,96,198,170,177,
        145,5,197,186,15,95,30,162,165,108
        ])

#基本統計量の確認
data.describe()
#Out[14]: 
#count    100.000000
#mean      99.120000
#std       57.713377
#min        3.000000
#25%       55.750000
#50%       99.000000
#75%      148.500000
#max      198.000000
#dtype: float64

#範囲(range)
range_data = max(data)-min(data)
print(range_data)
#Out[15]: 195

どうやら一様に分布してそうなのがうかがえます。

では、ここからが度数分布表の作成です。

'''
度数分布表を作る
'''
#-----
# スタージェスの公式(Sturges' formula)から階級の数を求める
#-----
from math import log
class_size = 1 + log(len(data), 2)
print(class_size)
#7.643856189774725
#よって階級の数は8

#-----
# 階級幅を求める
#-----
class_width =(max(data)-min(data))/8 #分母は階級の数、分子は範囲。
print(class_width)
#24.375
#よって階級幅は25

#-----
# 階級に振り分ける
#-----
#各観測値を階級値にする
def Frequency_Distribution(data, class_width):
    cut_data = []
    for row in data:
        cut = row // class_width
        cut_data.append(cut)
    return cut_data

#頻度を数える
Frequency_data = pd.Series(Frequency_Distribution(data, 25)).value_counts()
print(Frequency_data)

#インデックスでソート
F_data = Frequency_data.sort_index()
#インデックスの名前を変える
F_data.index = ['0~24','25~49','50~74','75~99','100~124','125~149','150~174','175~200']

#-----
# 度数分布表
#-----
print(F_data)#F_dataが完成した度数分布表
#0~24       14
#25~49       8
#50~74      17
#75~99      12
#100~124    12
#125~149    12
#150~174    15
#175~200    10
#dtype: int64

もっとスマートな方法がありましたら是非教えてください。