pandasとnumpyの標準偏差の計算の定義

pandasとnumpyで標準偏差を使った式を計算したときに、微妙に結果が違って調べたのでメモ。

github

  • githubのjupyter notebook形式のファイルはこちら

google colaboratory

  • google colaboratory で実行する場合はこちら

実行環境

!sw_vers
ProductName:	macOS
ProductVersion:	11.6.7
BuildVersion:	20G630
!python -V
Python 3.8.13

何も考えず実行

import pandas as pd
import numpy as np

pd.Series([i for i in range(5)]).std()
1.5811388300841898
np.std([i for i in range(5)])
1.4142135623730951

両者の結果が異なる。 ドキュメントを確認すると、numpyがデフォルトで自由度$n$、pandasが自由度$n-1$で計算しているからである。

  • 自由度 $n$

$$ s=\sqrt{\frac{1}{n} \sum_{i=1}^{n}\left(x_{i}-\bar{x}\right)^{2}} $$

  • 自由度 $n - 1$

$$ s=\sqrt{\frac{1}{n-1} \sum_{i=1}^{n}\left(x_{i}-\bar{x}\right)^{2}} $$

引数で自由度を明示すれば一致する。

print(pd.Series([i for i in range(5)]).std(ddof=0))
print(np.std([i for i in range(5)], ddof=0))
1.4142135623730951
1.4142135623730951
print(pd.Series([i for i in range(5)]).std(ddof=1))
print(np.std([i for i in range(5)], ddof=1))
1.5811388300841898
1.5811388300841898

定義通り計算すると、以下の通りで結果は一致する。

np.sqrt(np.sum(np.array([i * i for i in range(5)]) - np.power(np.mean([i for i in range(5)]), 2)) / 5)
1.4142135623730951
np.sqrt(np.sum(np.array([i * i for i in range(5)]) - np.power(np.mean([i for i in range(5)]), 2)) / 4)
1.5811388300841898

データ量が多くなればほとんど差はなくなるが、値が微妙に違う結果になって調べたのでメモ。