我没能找到这个具体问题的答案。我的数据看起来像:
df = pd.DataFrame({'Product': ['Alpha', 'Alpha', 'Alpha', 'Alpha','Alpha', 'Beta', 'Beta', 'Beta','Beta', 'Gamma', 'Gamma', 'Gamma','Delta','Delta','Epsilon','Epsilon','Epsilon','Epsilon'],'Age': [0,1,2,5,8,0,2,3,5,1,3,2,8,5,1,5,4,2],'Quantity': [114,82,15,35,27,63,32,55,87,50,4,22,6,96,94,3,64,110]})
产品 | 年龄 | 数量 |
---|---|---|
阿尔法 | 0 | 114 |
阿尔法 | 1 | 82 |
阿尔法 | 2 | 15 |
阿尔法 | 5 | 35 |
阿尔法 | 8 | 27 |
测试版 | 0 | 63 |
测试版 | 2 | 32 |
测试版 | 3 | 55 |
测试版 | 5 | 87 |
伽玛 | 1 | 50 |
伽玛 | 3 | 4 |
伽玛 | 2 | 22 |
三角洲 | 8 | 6 |
三角洲 | 5 | 96 |
小量 | 1 | 94 |
小量 | 5 | 3 |
小量 | 4 | 64 |
小量 | 2 | 110 |
我正在寻找的是年龄的任意百分位数,按产品细分,假设有数量,e,g.:
产品 | 第 70 个百分位(年) | 90%(年) |
---|---|---|
阿尔法 | 0 | 2 |
测试版 | 5 | 5 |
伽玛 | 2 | 2 |
三角洲 | 5 | 5 |
小量 | 2 | 4 |
这是一种方法:
df.reindex
使用np.repeat
与列“数量”作为重复。df.groupby
),选择“年龄”列,然后将 .quantile
与您选择的百分位数一起应用:[0.7, 0.9]
.Series.unstack
上使用
level 1
,然后再次应用df.reindex
,这次使用来自df['Product']
(Series.unique
)的唯一值。这重新建立了产品价值的顺序。import pandas as pd
import numpy as np
perc = [0.7,0.9]
res = (df.reindex(np.repeat(df.index, df['Quantity']))
.groupby('Product')['Age'].quantile(perc)
.unstack(1)
.reindex(df['Product'].unique())
)
res.columns = [f"{int(col*100)}th Percentile (years)" for col in res.columns]
res.index.name = None
res
70th Percentile (years) 90th Percentile (years)
Alpha 1.0 5.0
Beta 5.0 5.0
Gamma 2.0 2.0
Delta 5.0 5.0
Epsilon 2.0 4.0
Chain
res.astype(int)
,如果你想要整数。顺便说一下,您想要的输出包含一个错误。对于“Alpha”,您有 70% = 0
和 90% = 2
,但它们应该分别是 1
和 5
。
您需要通过重复每个年龄段的数量来获得加权百分位数。您可以为此创建一个自定义函数并将其应用于每个组:
import numpy as np
def weighted_percentile(df, p):
arr = np.percentile(np.repeat(df['Age'], df['Quantity']), p)
return pd.Series(arr).rename(lambda x: f'{p[x]}th Percentile (years)')
out = (df.groupby('Product', as_index=False, sort=False)
.apply(weighted_percentile, p=[70, 90]))
输出:
>>> out
Product 70th Percentile (years) 90th Percentile (years)
0 Alpha 1.0 5.0
1 Beta 5.0 5.0
2 Gamma 2.0 2.0
3 Delta 5.0 5.0
4 Epsilon 2.0 4.0