我有一组数据和一组用于创建垃圾箱的阈值:
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
中,最小的bin应该从第0个百分位开始。然后是下一个箱子,例如,第20百分位数。因此,如果data
中的值介于data
的第0和第20个百分位之间,则它属于第一个bin
。
我调查了大熊猫rank(pct=True)
,但似乎无法正确完成。
建议?
答案 0 :(得分:4)
您可以计算数据数组中每个元素的百分位数,如上一个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])