NumPy:パーセンタイルを求める(percentile, quantile)

パーセンタイルは、データを小さい順に並べたとき「下から何%の位置にある値か」を表す指標です。NumPy では percentilequantile で計算できます。

percentile:パーセント指定

np.percentile() は、0〜100 のパーセント値で位置を指定します。

import numpy as np

data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

# 50パーセンタイル(中央値)
print(np.percentile(data, 50))  # 5.5

# 25パーセンタイル(第1四分位数)
print(np.percentile(data, 25))  # 3.25

# 75パーセンタイル(第3四分位数)
print(np.percentile(data, 75))  # 7.75

複数のパーセンタイルをまとめて取得することもできます。

# 25, 50, 75パーセンタイルを一度に取得
result = np.percentile(data, [25, 50, 75])
print(result)  # [3.25 5.5  7.75]

quantile:0〜1の割合で指定

np.quantile() は、0〜1 の小数で位置を指定します。percentile の 50 は quantile では 0.5 に相当します。

data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

# 0.5(50%)= 中央値
print(np.quantile(data, 0.5))  # 5.5

# 四分位数
print(np.quantile(data, [0.25, 0.5, 0.75]))
# [3.25 5.5  7.75]

percentile と quantile の使い分け

percentile

0〜100 のパーセントで指定。「上位10%」などの表現に馴染みやすい

quantile

0〜1 の割合で指定。統計学的な分位数の定義に沿っている

どちらを使っても結果は同じです。好みや文脈に合わせて選んでください。

補間方法の指定

データが離散的な場合、指定したパーセンタイルがぴったり存在しないことがあります。そのとき、どう補間するかを method 引数で指定できます。

data = np.array([1, 2, 3, 4, 5])

# デフォルト(線形補間)
print(np.percentile(data, 40))  # 2.6

# 最も近い値を選ぶ
print(np.percentile(data, 40, method='nearest'))  # 2

# 切り捨て
print(np.percentile(data, 40, method='lower'))  # 2

# 切り上げ
print(np.percentile(data, 40, method='higher'))  # 3

デフォルトの線形補間が一般的に使われます。

多次元配列での使用

axis を指定すると、特定の軸方向にパーセンタイルを計算できます。

a = np.array([[10, 7, 4],
              [3, 2, 1]])

# 全体の50パーセンタイル
print(np.percentile(a, 50))  # 3.5

# 列ごとの50パーセンタイル
print(np.percentile(a, 50, axis=0))  # [6.5 4.5 2.5]

# 行ごとの50パーセンタイル
print(np.percentile(a, 50, axis=1))  # [7. 2.]

外れ値の検出

パーセンタイルは外れ値の検出によく使われます。四分位範囲(IQR)を使った方法が一般的です。

data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 100])

q1 = np.percentile(data, 25)
q3 = np.percentile(data, 75)
iqr = q3 - q1

# 外れ値の閾値
lower_bound = q1 - 1.5 * iqr
upper_bound = q3 + 1.5 * iqr

print(f"外れ値の範囲外: {lower_bound:.1f}{upper_bound:.1f}")
# 外れ値の範囲外: -6.5 〜 17.0

# 100は外れ値
outliers = data[(data < lower_bound) | (data > upper_bound)]
print(f"外れ値: {outliers}")  # 外れ値: [100]