百分位,百分位数(percentile)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了百分位,百分位数(percentile)相关的知识,希望对你有一定的参考价值。
参考技术A 百分位(p) :没啥好说的,就是百分数,比如2%,39%等等,没有量纲。
百分位数(P) :对于某个数值序列,根据某个 百分位p 计算得到的值就是该百分位对应的 百分位数P ,百分位数有量纲。假如原来序列表示考试成绩,则某个百分位数也是成绩。
百分位数的计算没有统一的标准公式 ,但有一个基本原则, 即当序列元素足够多或者序列满足连续概率分布时,不同百分位数计算方式得到的结果应该是一致的。
假设原始数值序列S0的长度为n,求百分位p的百分位数?
计算过程如下:
(1)序列排序:将序列从小到大排序,得到序列S1
(2)百分位序号计算:1+(n-1)×p=i+j,其中i是整数部分,j是小数部分;
(注意:这里的百分位序号指的是百分位对应序列中的位置,正常情况下它是个正整数,但实际上计算结果会出现小数,最简单处理方式就是取前一个或后一个最近的整数位置,但这么做有一个问题,如果前后两个位置对应的值差别很大,那么取前和取后得到的百分位数P差别就很大,于是另一种方式就是根据计算的百分位序号并结合前后两个位置的数据插值得到最终的百分位数P,随着插值方式的变化,P也不同,其中Excel和numpy的插值方式如下:)
(3)百分位数:P=S1(i)+[S(i+1)-S(i)]×j
(说明:这个插值思想很简单,S1(i)表示前一个位置的值,[S(i+1)-S(i)]×j表示前后两个位置对应值的间隔乘以位置的小数部分j,就是把j作为比例去截取间隔。)
例子:
求考试成绩序列S0=[37 12 72 9 75 5 79 64 16 1 76 71 6 25 50 20 18 84 11 28],单位是“分”。
在百分位p=80%的百分位数?
解:
S1=[ 1 5 6 9 11 12 16 18 20 25 28 37 50 64 71 72 75 76 79 84]
序列长度为n=20
则百分位序号为:1+(20-1)×80%=16.2,即i=16,j=0.2
则百分位数为:P=S1(16)+[S(17)-S(16)]×0.2=72+(75-72)*0.2=72.6分
这个结果的意思是80%的人在72.6分以下。
计算特定组的百分位数
【中文标题】计算特定组的百分位数【英文标题】:Calculating percentile for specific groups 【发布时间】:2016-08-25 00:01:56 【问题描述】:我有 3 列。 Product Id
、Price
、Group
(值 A、B、C、D)
我想获取每个组的价格百分位数,我正在运行以下代码。
for group, price in df.groupby(['group']):
df['percentile'] = np.percentile(df['price'],60)
每组的百分位列只有一个值 3.44。
每组的预期值为2.12, 3.43, 3.65, 4.76. 8.99
。
这里出了什么问题,请告诉我。
【问题讨论】:
【参考方案1】:我认为你可以在循环中使用不是所有的 DataFrame
df
与列 price
,而是将 price
与列 price
一起使用:
import pandas as pd
import numpy as np
np.random.seed(1)
df = pd.DataFrame(np.random.randint(10, size=(5,3)))
df.columns = ['Product Id','group','price']
print df
Product Id group price
0 5 8 9
1 5 0 0
2 1 7 6
3 9 2 4
4 5 2 4
for group, price in df.groupby(['group']):
print np.percentile(df['price'],60)
4.8
4.8
4.8
4.8
group
for group, price in df.groupby(['group']):
print np.percentile(price['price'],60)
0.0
4.0
6.0
9.0
np.percentile
的另一种解决方案是输出Serie
:
print df.groupby(['group'])['price'].apply(lambda x: np.percentile(x,60))
group
0 0.0
2 4.0
7 6.0
8 9.0
Name: price, dtype: float64
DataFrameGroupBy.quantile
的解决方案:
print df.groupby(['group'])['price'].quantile(.6)
group
0 0.0
2 4.0
7 6.0
8 9.0
Name: price, dtype: float64
通过评论编辑:
如果您需要新列,请使用transform
、docs:
>>> np.random.seed(1)
>>> df = pd.DataFrame(np.random.randint(10,size=(20,3)))
>>> df.columns = ['Product Id','group','price']
>>> df
Product Id group price
0 5 8 9
1 5 0 0
2 1 7 6
3 9 2 4
4 5 2 4
5 2 4 7
6 7 9 1
7 7 0 6
8 9 9 7
9 6 9 1
10 0 1 8
11 8 3 9
12 8 7 3
13 6 5 1
14 9 3 4
15 8 1 4
16 0 3 9
17 2 0 4
18 9 2 7
19 7 9 8
>>> df['percentil'] = df.groupby(['group'])['price'].transform(lambda x: x.quantile(.6))
>>> df
Product Id group price percentil
0 5 8 9 9.0
1 5 0 0 4.4
2 1 7 6 4.8
3 9 2 4 4.6
4 5 2 4 4.6
5 2 4 7 7.0
6 7 9 1 5.8
7 7 0 6 4.4
8 9 9 7 5.8
9 6 9 1 5.8
10 0 1 8 6.4
11 8 3 9 9.0
12 8 7 3 4.8
13 6 5 1 1.0
14 9 3 4 9.0
15 8 1 4 6.4
16 0 3 9 9.0
17 2 0 4 4.4
18 9 2 7 4.6
19 7 9 8 5.8
【讨论】:
不确定这是否符合我的目的。我不需要打印输出。我想在同一数据框 df 中创建一个列“百分位数”,每个组的百分位数为 60。这意味着我的 df 现在将有 4 列,产品 ID、价格、组和百分位数。在下一步中,我想使用这个新的“百分位数”创建另一个列,以便我可以按其“价格”对每个“组”中的产品 ID 进行分类。我的下一行是 df['price_point'] = np.where(df['retailprice'] >= k,'high','low')【参考方案2】:你可以试试 pandas quantile
df[['group', 'price']].groupby('group').quantile(.6)
返回请求轴上给定分位数的值,一个 la numpy.percentile。
【讨论】:
以上是关于百分位,百分位数(percentile)的主要内容,如果未能解决你的问题,请参考以下文章