web-dev-qa-db-ja.com

python / numpyでパーセンタイルを計算するにはどうすればよいですか?

シーケンスまたは単一次元のnumpy配列のパーセンタイルを計算する便利な方法はありますか?

Excelのパーセンタイル関数に似たものを探しています。

私はNumPyの統計参照を調べましたが、これを見つけることができませんでした。私が見つけることができたのは中央値(50パーセンタイル)だけですが、より具体的なものではありません。

176
Uri

SciPy Stats パッケージに興味があるかもしれません。 百分位数関数 が必要です。他にも多くの統計的利点があります。

percentile()使用可能numpyにあります。

import numpy as np
a = np.array([1,2,3,4,5])
p = np.percentile(a, 50) # return 50th percentile, e.g median.
print p
3.0

このチケット は、percentile()をすぐにnumpyに統合しないと信じさせてくれます。

233
Jon W

ちなみに、scipyに依存したくない場合のために パーセンタイル関数の純粋なPython実装 があります。関数は以下にコピーされます:

## {{{ http://code.activestate.com/recipes/511478/ (r1)
import math
import functools

def percentile(N, percent, key=lambda x:x):
    """
    Find the percentile of a list of values.

    @parameter N - is a list of values. Note N MUST BE already sorted.
    @parameter percent - a float value from 0.0 to 1.0.
    @parameter key - optional key function to compute value from each element of N.

    @return - the percentile of the values
    """
    if not N:
        return None
    k = (len(N)-1) * percent
    f = math.floor(k)
    c = math.ceil(k)
    if f == c:
        return key(N[int(k)])
    d0 = key(N[int(f)]) * (c-k)
    d1 = key(N[int(c)]) * (k-f)
    return d0+d1

# median is 50th percentile.
median = functools.partial(percentile, percent=0.5)
## end of http://code.activestate.com/recipes/511478/ }}}
62
Boris Gorelik
import numpy as np
a = [154, 400, 1124, 82, 94, 108]
print np.percentile(a,95) # gives the 95th percentile
25
richie

Numpyを使用せずにpythonのみを使用してパーセンタイルを計算する方法を次に示します。

import math

def percentile(data, percentile):
    size = len(data)
    return sorted(data)[int(math.ceil((size * percentile) / 100)) - 1]

p5 = percentile(mylist, 5)
p25 = percentile(mylist, 25)
p50 = percentile(mylist, 50)
p75 = percentile(mylist, 75)
p95 = percentile(mylist, 95)
11
Ashkan

私が通常目にするパーセンタイルの定義は、結果として値のPパーセントが検出される、提供されたリストからの値を期待します。そのためには、より単純な関数を使用できます。

def percentile(N, P):
    """
    Find the percentile of a list of values

    @parameter N - A list of values.  N must be sorted.
    @parameter P - A float value from 0.0 to 1.0

    @return - The percentile of the values.
    """
    n = int(round(P * len(N) + 0.5))
    return N[n-1]

# A = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
# B = (15, 20, 35, 40, 50)
#
# print percentile(A, P=0.3)
# 4
# print percentile(A, P=0.8)
# 9
# print percentile(B, P=0.3)
# 20
# print percentile(B, P=0.8)
# 50

提供されたリストから値のPパーセントが検出される値以下を取得する場合は、次の簡単な変更を使用します。

def percentile(N, P):
    n = int(round(P * len(N) + 0.5))
    if n > 1:
        return N[n-2]
    else:
        return N[0]

または、@ ijustlovemathによって提案された単純化を使用して:

def percentile(N, P):
    n = max(int(round(P * len(N) + 0.5)), 2)
    return N[n-2]
10
mpounsett

scipy.statsモジュールを確認します。

 scipy.stats.scoreatpercentile
7
Evert

Python 3.8以降、標準ライブラリには quantiles モジュールの一部として statistics 関数が付属しています。

from statistics import quantiles

quantiles([1, 2, 3, 4, 5], n=100)
# [0.06, 0.12, 0.18, 0.24, 0.3, 0.36, 0.42, 0.48, 0.54, 0.6, 0.66, 0.72, 0.78, 0.84, 0.9, 0.96, 1.02, 1.08, 1.14, 1.2, 1.26, 1.32, 1.38, 1.44, 1.5, 1.56, 1.62, 1.68, 1.74, 1.8, 1.86, 1.92, 1.98, 2.04, 2.1, 2.16, 2.22, 2.28, 2.34, 2.4, 2.46, 2.52, 2.58, 2.64, 2.7, 2.76, 2.82, 2.88, 2.94, 3.0, 3.06, 3.12, 3.18, 3.24, 3.3, 3.36, 3.42, 3.48, 3.54, 3.6, 3.66, 3.72, 3.78, 3.84, 3.9, 3.96, 4.02, 4.08, 4.14, 4.2, 4.26, 4.32, 4.38, 4.44, 4.5, 4.56, 4.62, 4.68, 4.74, 4.8, 4.86, 4.92, 4.98, 5.04, 5.1, 5.16, 5.22, 5.28, 5.34, 5.4, 5.46, 5.52, 5.58, 5.64, 5.7, 5.76, 5.82, 5.88, 5.94]
quantiles([1, 2, 3, 4, 5], n=100)[49] # 50th percentile (e.g median)
# 3.0

quantiles は、指定された分布distに対して、n分位間隔(等しい確率でdistn連続間隔に分割)を分離するn - 1カットポイントのリストを返します。

statistics.quantiles(dist、*、n = 4、method = 'exclusive')

ここで、n、この場合(percentiles)は100です。

2
Xavier Guihot

シリーズのパーセンタイルを計算するには、次を実行します。

from scipy.stats import rankdata
import numpy as np

def calc_percentile(a, method='min'):
    if isinstance(a, list):
        a = np.asarray(a)
    return rankdata(a, method=method) / float(len(a))

例えば:

a = range(20)
print {val: round(percentile, 3) for val, percentile in Zip(a, calc_percentile(a))}
>>> {0: 0.05, 1: 0.1, 2: 0.15, 3: 0.2, 4: 0.25, 5: 0.3, 6: 0.35, 7: 0.4, 8: 0.45, 9: 0.5, 10: 0.55, 11: 0.6, 12: 0.65, 13: 0.7, 14: 0.75, 15: 0.8, 16: 0.85, 17: 0.9, 18: 0.95, 19: 1.0}
2
Roei Bahumi

答えが入力numpy配列のメンバーになる必要がある場合:

デフォルトでは、numpyのパーセンタイル関数は、出力を入力ベクトルの2つの隣接エントリの線形加重平均として計算することを追加するだけです。場合によっては、返されたパーセンタイルをベクトルの実際の要素にしたい場合があります。この場合、v1.9.0以降では、「low」、「higher」、「nearest」のいずれかで「補間」オプションを使用できます。

import numpy as np
x=np.random.uniform(10,size=(1000))-5.0

np.percentile(x,70) # 70th percentile

2.075966046220879

np.percentile(x,70,interpolation="nearest")

2.0729677997904314

後者はベクトルの実際のエントリですが、前者はパーセンタイルに隣接する2つのベクトルエントリの線形補間です

1
Adrian Tompkins

シリーズの場合:記述関数を使用

次の列salesおよびidを持つdfがあるとします。売上のパーセンタイルを計算する場合、次のように機能します。

df['sales'].describe(percentiles = [0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1])

0.0: .0: minimum
1: maximum 
0.1 : 10th percentile and so on
0
ashwini