百分位数与Pandas groupby / aggregate相结合

时间:2014-09-03 17:18:59

标签: python pandas

我正在尝试创建一个函数来计算数据框中多个变量的不同百分位数。我正在使用dict和Pandas聚合函数,如下所示:

dfG = df.groupby('ClinicalEpisode')
dfA = dfG.agg( { 'Total LOS' : 
                 {'Total LOS P5' : 'pd.quantile(.05)',
                  'Total LOS P10' : 'pd.quantile(.10)',
                  'Total LOS P15' : 'pd.quantile(.15)',
                  'Total LOS P20' : 'pd.quantile(.20)',
                  'Total LOS P25' : 'pd.quantile(.25)',
                  'Total LOS P30' : 'pd.quantile(.30)',
                  'Total LOS P33' : 'pd.quantile(.333333)',
                  'Total LOS P35' : 'pd.quantile(.35)',
                  'Total LOS P40' : 'pd.quantile(.40)',
                  'Total LOS P50' : 'pd.quantile(.50)',
                  'Total LOS P75' : 'pd.quantile(.75)',
                  'Total LOS P80' : 'pd.quantile(.80)',
                  'Total LOS P90' : 'pd.quantile(.90)'},
            'Trigger SNF LOS' :
                 {'Trigger SNF LOS P5' : 'pd.quantile(.05)',
                  'Trigger SNF LOS P10' : 'pd.quantile(.10)',
                  'Trigger SNF LOS P15' : 'pd.quantile(.15)',
                  'Trigger SNF LOS P20' : 'pd.quantile(.20)',
                  'Trigger SNF LOS P25' : 'pd.quantile(.25)',
                  'Trigger SNF LOS P30' : 'pd.quantile(.30)',
                  'Trigger SNF LOS P33' : 'pd.quantile(.333333)',
                  'Trigger SNF LOS P35' : 'pd.quantile(.35)',
                  'Trigger SNF LOS P40' : 'pd.quantile(.40)',
                  'Trigger SNF LOS P50' : 'pd.quantile(.50)',
                  'Trigger SNF LOS P75' : 'pd.quantile(.75)',
                  'Trigger SNF LOS P80' : pd.quantile(.80),
                  'Trigger SNF LOS P90' : pd.quantile(.90)}
            })

我尝试过许多不同的功能,但似乎没有任何功能可以用于dict。

FWIW,我能够使用以下代码一次计算一个变量的这些分位数:

dfA = df.groupby('ClinicalEpisode')['Total LOS'].quantile(
    [.05, .1, .15, .2, .25, .3, .3333, .35, .4, .5, .6, .7, .75, .8, .9, .95])

不过,我真的希望能够使用dict方法。我只是卡住了。

1 个答案:

答案 0 :(得分:5)

仅供参考,提供样本数据和预期输出是有帮助的。你也应该更明确而不是"我只是被卡住了#34;。

你有两个问题

  1. 没有pandas quantile方法。有DataFrame.quantile方法,但我们无法使用它。这与你的第二个问题有关。
  2. GroupBy对象上的聚合方法需要采用数组并返回单个值的函数。我们将使用numpy的percentile,其中数组和百分位数q介于0和100之间。就像我说的那样,groupby期待一个只是<的函数/ em>接受一个数组,所以让我们使用functools.partial
  3. 解决这个问题

    以下是如何做到这一点:

    In [62]: percentiles = [5, 10, 15, 20, 25, 30, 33, 35, 40, 50, 75, 80, 90]
    
    In [64]: from functools import partial
    
    In [65]: aggs = {'P {}'.format(q): partial(np.percentile, q=q) for q in percentiles}
    In [66]: aggs
    Out[66]: 
    {'P 40': functools.partial(<function percentile at 0x10abde378>, q=40),
     'P 90': functools.partial(<function percentile at 0x10abde378>, q=90),
    ...}
    

    现在我们可以传入aggs

    In [71]: df = pd.DataFrame(np.random.randn(20, 4))
    
    In [72]: df['g'] = np.random.randint(0, 2, 20)
    
    In [73]: df.groupby('g').agg({0: aggs, 1: aggs, 2:aggs})
    Out[73]: 
              0                                                              \
           P 40      P 90      P 80      P 20      P 30      P 35      P 75   
    g                                                                         
    0 -1.451969 -0.134986 -0.466439 -1.726501 -1.475623 -1.463796 -0.632166   
    1  0.249210  1.363307  1.029008 -0.644655 -0.241753  0.180993  0.952654   
    
                                                                          1  \
            P 5      P 15      P 25    P 33      P 50      P 10      P 40   
    g                                                                         
    0 -2.443653 -1.965552 -1.487451 -2.666927 -1.428315 -2.204603 -1.359988   
    1 -1.423351 -0.728314 -0.491645 -1.507900  0.381779 -1.126839  0.261025   
    
    ....
    

    如果您想要Total LOS ...,可以修改字典中的键。我只有P [percentile],因为他们来自的列位于MultiIndex的上层。