Как вычислить процентили с помощью python / numpy?
есть ли удобный способ вычисления процентилей для последовательности или одномерного массива numpy?
Я ищу что-то похожее на функцию Excel процентиля.
Я посмотрел в справочнике статистики NumPy и не смог найти это. Все, что я смог найти-это медиана (50-й процентиль), а не что-то более конкретное.
8 ответов:
вы можете быть заинтересованы в Статистика SciPy пакета. Он имеет функция процентиль вы после и многих других статистических лакомств.
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
этот билет заставляет меня поверить, что они не будут интегрироваться библиотеки numpy в любое время.
кстати, есть реализация Pure-Python процентильной функции, в случае, если кто-то не хочет зависеть от scipy. Функция копируется ниже:
## {{{ 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/ }}}
import numpy as np a = [154, 400, 1124, 82, 94, 108] print np.percentile(a,95) # gives the 95th percentile
определение процентиля, которое я обычно вижу, ожидает в результате значение из предоставленного списка, ниже которого находятся 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]
вот как это сделать без 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)
чтобы вычислить процентиль ряда, выполните:
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}
в случае, если вам нужен ответ, чтобы быть членом входного массива numpy:
просто чтобы добавить, что функция процентиля в numpy по умолчанию вычисляет выход как линейное взвешенное среднее двух соседних записей во входном векторе. В некоторых случаях люди могут захотеть, чтобы возвращенный процентиль был фактическим элементом вектора, в этом случае с v1. 9. 0 и далее вы можете использовать опцию "интерполяция", либо "ниже", "выше", либо "ближайший."
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последний является фактической записью в векторе, в то время как первый является линейной интерполяцией двух векторных записей, которые граничат с процентилем
Comments