2016-09-03 10 views
0

У меня есть набор данных, а также множество порогов для создания бункеров:Вычисление процентиля бункеров от оцифровки numpy?

data = np.array([0.01, 0.02, 1, 1, 1, 2, 2, 8, 8, 4.5, 6.6]) 
thresholds = np.array([0,5,10]) 
bins = np.digitize(data, thresholds, right=True) 

Для каждого из элементов в bins, я хочу знать основной процентиль. Например, в bins наименьший бит должен начинаться с 0-го процентиля. Затем следующий бин, например, 20-й процентиль. Таким образом, если значение в data находится между 0-м и 20-м процентилем data, оно относится к первому bin.

Я заглянул в pandas rank(pct=True), но, похоже, не получается сделать это правильно.

Предложения?

ответ

2

Вы можете вычислить процентиль для каждого элемента массива данных, как описано в предыдущем вопросе StackOverflow (Map each list value to its corresponding percentile).

import numpy as np 
from scipy import stats 
data = np.array([0.01, 0.02, 1, 1, 1, 2, 2, 8, 8, 4.5, 6.6]) 

Метод 1: Использование scipy.stats.percentileofscore:

data_percentile = np.array([stats.percentileofscore(data, a) for a in data]) 
data_percentile 
Out[1]: 
array([ 9.09090909, 18.18181818, 36.36363636, 36.36363636, 
     36.36363636, 59.09090909, 59.09090909, 95.45454545, 
     95.45454545, 72.72727273, 81.81818182]) 

Метод 2: Использование scipy.stats.rankdata и нормализующее 100 (быстрее):

ranked = stats.rankdata(data) 
data_percentile = ranked/len(data)*100 
data_percentile 
Out[2]: 
array([ 9.09090909, 18.18181818, 36.36363636, 36.36363636, 
     36.36363636, 59.09090909, 59.09090909, 95.45454545, 
     95.45454545, 72.72727273, 81.81818182]) 

Теперь, когда у вас есть список процентили, вам могут использовать их как прежде, используя numpy.digitize:

bins_percentile = [0,20,40,60,80,100] 
data_binned_indices = np.digitize(data_percentile, bins_percentile, right=True) 
data_binned_indices 
Out[3]: 
array([1, 1, 2, 2, 2, 3, 3, 5, 5, 4, 5], dtype=int64) 

Это дает вам данные, закодированные в соответствии с показателями вашего выбранного списка процентилей. При желании вы также можете вернуть фактические (верхние) процентили с использованием numpy.take:

data_binned_percentiles = np.take(bins_percentile, data_binned_indices) 
data_binned_percentiles 
Out[4]: 
array([ 20, 20, 40, 40, 40, 60, 60, 100, 100, 80, 100])