ハンバーガー統計学にようこそ!の第1章をPythonでやってみたもの。
準備
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
1.1 ポテトの長さの平均は
waku = pd.Series(
[3.5, 4.2, 4.9, 4.6, 2.8, 5.6, 4.2, 4.9, 4.4, 3.7,
3.8, 4.0, 5.2, 3.9, 5.6, 5.3, 5.0, 4.7, 4.0, 3.1,
5.8, 3.6, 6.0, 4.2, 5.7, 3.9, 4.7, 5.3, 5.5, 4.7,
6.4, 3.8, 3.9, 4.2, 5.1, 5.1, 4.1, 3.6, 4.2, 5.0,
4.2, 5.2, 5.3, 6.4, 4.4, 3.6, 3.7, 4.2, 4.8]
)
mogu = pd.Series(
[4.5, 4.2, 3.9, 6.6, 0.8, 5.6, 3.2, 6.9, 4.4, 4.7,
3.8, 3.0, 3.2, 4.9, 7.6, 3.3, 7.0, 3.7, 3.0, 4.1,
5.8, 4.6, 4.0, 2.2, 7.7, 3.9, 6.7, 3.3, 7.5, 2.7,
5.4, 5.8, 5.9, 3.2, 5.1, 3.1, 6.1, 4.6, 2.2, 4.0,
6.4, 5.2, 3.3, 6.4, 6.4, 2.6, 2.6, 5.2, 5.8]
)
waku.sum()
waku.mean()
mogu.sum()
mogu.mean()
箱ひげ図はDataFrameにしてから描画すると簡単。
df = pd.DataFrame({"waku":waku, "mogu":mogu})
df.boxplot(grid=False)
plt.show()
1.2 度数分布
度数分布はpandas.cut
で分割し、これに基づいてpandas.groupby
で元データを分割、グループごとにcount
を適用するという手順をとることで得られる(cf. pandas で年齢階級をつくる - Qiita)。
waku.groupby(pd.cut(waku, np.arange(0, 9, 1))).count()
(0, 1] 0
(1, 2] 0
(2, 3] 1
(3, 4] 14
(4, 5] 19
(5, 6] 13
(6, 7] 2
(7, 8] 0
dtype: int64
mogu.groupby(pd.cut(mogu, np.arange(0, 9, 1))).count()
(0, 1] 1
(1, 2] 0
(2, 3] 7
(3, 4] 13
(4, 5] 8
(5, 6] 9
(6, 7] 8
(7, 8] 3
dtype: int64
ヒストグラムの方が作るのは簡単な印象。
df.hist(bins=np.arange(0,9,1),
sharey=True,
grid=False,
layout=(2,1))
plt.show()
df.var(ddof=0)
mogu 2.584898
waku 0.680816
dtype: float64
df.std(ddof=0)
mogu 1.607762
waku 0.825116
dtype: float64
ddof
はDelta Degrees of Freedom
で、自由度はサンプルサイズをNとしてN - ddof
として指定される。Pandasの場合はデフォルトが1なので、何も指定しないと不偏分散およびそれに基づく標準偏差が計算される。今回はテキストに合わせるためにあえて0を指定している。
なお、numpy.var
およびnumpy.std
も分散および標準偏差を計算するメソッドであり、ddof
という同名の引数が用意されているが、なんとこちらはデフォルトが0である。
1.9 通過テスト
df = pd.DataFrame({
"桜組" : [78, 62, 81, 59, 72, 68, 75, 65, 80, 60, 78, 62, 70],
"桃組" : [70, 72, 68, 75, 65, 71, 69, 76, 64, 80, 60, 73, 67],
"柳組" : [57, 59, 55, 62, 52, 58, 56, 63, 51, 67, 47, 60, 54]
})
平均、分散、標準偏差はdf.mean()
, df.var()
, df.std()
でそれぞれ計算できるが、df.describe()
を使うとデータ数、平均、標準偏差といわゆる五数要約(最大値、75%点、中央値、25%点、最小値)を確認できる。
df.describe()
柳組 桃組 桜組
count 13.000000 13.000000 13.000000
mean 57.000000 70.000000 70.000000
std 5.400617 5.400617 7.937254
min 47.000000 60.000000 59.000000
25% 54.000000 67.000000 62.000000
50% 57.000000 70.000000 70.000000
75% 60.000000 73.000000 78.000000
max 67.000000 80.000000 81.000000
また、scipy.stats.describe()
ではデータ数、最大値、最小値、平均、分散、歪度、尖度を確認でき、ddof
で自由度を指定できる。
import scipy as sp
sp.stats.describe(df)
DescribeResult(nobs=13, minmax=(array([47, 60, 59]), array([67, 80, 81])), mean=array([ 57., 70., 70.]), variance=array([ 29.16666667, 29.16666667, 63. ]), skewness=array([ 0., 0., 0.]), kurtosis=array([-0.44902857, -0.44902857, -1.47721928]))
ついでに日本語ラベル付きのヒストグラムでも描いてみようと思って日本語表示に結構手間取った。seabornの設定でフォントを指定するとmatplotlibの設定もまとめて上書きされるので楽っぽい(cf.matplotlib と Seaborn の軸の日本語設定 - Qiita)。
import seaborn as sns
sns.set(font='Ricty')
df.hist()
plt.show()
seabornでも描いてみよう。
for i in df.columns:
ax = sns.distplot(df[i],
label=i,
bins = 4)
ax.legend()
plt.show()
適当にやっても綺麗に出力される印象(cf.python - Two seaborn distplots one same axis - Stack Overflow)。