计算相对于给定人口的百分位数排名
Compute percentile rank relative to a given population
我有 "reference population"(比如,v=np.random.rand(100)
),我想计算给定集合(比如,np.array([0.3, 0.5, 0.7])
)的百分位数排名。
很容易一一计算:
def percentile_rank(x):
return (v<x).sum() / len(v)
percentile_rank(0.4)
=> 0.4
(实际上,有一个 ootb scipy.stats.percentileofscore
- 但它 不 对向量起作用)。
np.vectorize(percentile_rank)(np.array([0.3, 0.5, 0.7]))
=> [ 0.33 0.48 0.71]
这产生了预期的结果,但我觉得应该有一个内置的。
我也会作弊:
pd.concat([pd.Series([0.3, 0.5, 0.7]),pd.Series(v)],ignore_index=True).rank(pct=True).loc[0:2]
0 0.330097
1 0.485437
2 0.718447
这有两点不好:
- 我不希望测试数据
[0.3, 0.5, 0.7]
成为排名的一部分。
- 我不想浪费时间计算参考人群的排名。
那么,惯用的方法是什么?
我认为pd.cut
可以做到
s=pd.Series([-np.inf,0.3, 0.5, 0.7])
pd.cut(v,s,right=False).value_counts().cumsum()/len(v)
Out[702]:
[-inf, 0.3) 0.37
[0.3, 0.5) 0.54
[0.5, 0.7) 0.71
dtype: float64
你的函数的结果
np.vectorize(percentile_rank)(np.array([0.3, 0.5, 0.7]))
Out[696]: array([0.37, 0.54, 0.71])
您可以使用 quantile
:
np.random.seed(123)
v=np.random.rand(100)
s = pd.Series(v)
arr = np.array([0.3,0.5,0.7])
s.quantile(arr)
输出:
0.3 0.352177
0.5 0.506130
0.7 0.644875
dtype: float64
设置:
In [62]: v=np.random.rand(100)
In [63]: x=np.array([0.3, 0.4, 0.7])
使用 Numpy 广播:
In [64]: (v<x[:,None]).mean(axis=1)
Out[64]: array([ 0.18, 0.28, 0.6 ])
检查:
In [67]: percentile_rank(0.3)
Out[67]: 0.17999999999999999
In [68]: percentile_rank(0.4)
Out[68]: 0.28000000000000003
In [69]: percentile_rank(0.7)
Out[69]: 0.59999999999999998
我知道我来晚了一点,但想补充一点 pandas 有另一种方法可以让 Series.rank
得到你想要的东西。只需使用 pct=True
选项。
我有 "reference population"(比如,v=np.random.rand(100)
),我想计算给定集合(比如,np.array([0.3, 0.5, 0.7])
)的百分位数排名。
很容易一一计算:
def percentile_rank(x):
return (v<x).sum() / len(v)
percentile_rank(0.4)
=> 0.4
(实际上,有一个 ootb scipy.stats.percentileofscore
- 但它 不 对向量起作用)。
np.vectorize(percentile_rank)(np.array([0.3, 0.5, 0.7]))
=> [ 0.33 0.48 0.71]
这产生了预期的结果,但我觉得应该有一个内置的。
我也会作弊:
pd.concat([pd.Series([0.3, 0.5, 0.7]),pd.Series(v)],ignore_index=True).rank(pct=True).loc[0:2]
0 0.330097
1 0.485437
2 0.718447
这有两点不好:
- 我不希望测试数据
[0.3, 0.5, 0.7]
成为排名的一部分。 - 我不想浪费时间计算参考人群的排名。
那么,惯用的方法是什么?
我认为pd.cut
可以做到
s=pd.Series([-np.inf,0.3, 0.5, 0.7])
pd.cut(v,s,right=False).value_counts().cumsum()/len(v)
Out[702]:
[-inf, 0.3) 0.37
[0.3, 0.5) 0.54
[0.5, 0.7) 0.71
dtype: float64
你的函数的结果
np.vectorize(percentile_rank)(np.array([0.3, 0.5, 0.7]))
Out[696]: array([0.37, 0.54, 0.71])
您可以使用 quantile
:
np.random.seed(123)
v=np.random.rand(100)
s = pd.Series(v)
arr = np.array([0.3,0.5,0.7])
s.quantile(arr)
输出:
0.3 0.352177
0.5 0.506130
0.7 0.644875
dtype: float64
设置:
In [62]: v=np.random.rand(100)
In [63]: x=np.array([0.3, 0.4, 0.7])
使用 Numpy 广播:
In [64]: (v<x[:,None]).mean(axis=1)
Out[64]: array([ 0.18, 0.28, 0.6 ])
检查:
In [67]: percentile_rank(0.3)
Out[67]: 0.17999999999999999
In [68]: percentile_rank(0.4)
Out[68]: 0.28000000000000003
In [69]: percentile_rank(0.7)
Out[69]: 0.59999999999999998
我知道我来晚了一点,但想补充一点 pandas 有另一种方法可以让 Series.rank
得到你想要的东西。只需使用 pct=True
选项。