Python、Pandas:多列分组数据的百分位数

问题描述 投票:0回答:2

我没能找到这个具体问题的答案。我的数据看起来像:

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
python pandas percentile
2个回答
0
投票

这是一种方法:

  • 应用
    df.reindex
    使用
    np.repeat
    与列“数量”作为重复。
  • 按“产品”列分组数据 (
    df.groupby
    ),选择“年龄”列,然后将
    .quantile
    与您选择的百分位数一起应用:
    [0.7, 0.9]
    .
  • 剩下的就是获得所需的形状:在索引Series.unstack
    上使用
    level 1
    ,然后再次应用
    df.reindex
    ,这次使用来自
    df['Product']
    Series.unique
    )的唯一值。这重新建立了产品价值的顺序。
  • 最后,在 for 循环中重命名您的列并删除添加的索引标签。
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


0
投票

您需要通过重复每个年龄段的数量来获得加权百分位数。您可以为此创建一个自定义函数并将其应用于每个组:

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
© www.soinside.com 2019 - 2024. All rights reserved.