将百分位数传递给pandas agg功能

时间:2013-07-10 18:22:47

标签: python numpy pandas

我想通过pandas的agg()函数传递numpy percentile()函数,如下所示,使用其他各种numpy统计函数。

现在我的数据框看起来像这样:

AGGREGATE   MY_COLUMN
A           10
A           12
B           5
B           9
A           84
B           22

我的代码看起来像这样:

grouped = dataframe.groupby('AGGREGATE')
column = grouped['MY_COLUMN']
column.agg([np.sum, np.mean, np.std, np.median, np.var, np.min, np.max])

上面的代码有效,但我想做类似

的事情
column.agg([np.sum, np.mean, np.percentile(50), np.percentile(95)])

即。指定从agg()

返回的各种百分位数

应该怎么做?

12 个答案:

答案 0 :(得分:61)

也许不是超级高效,但一种方法是自己创建一个函数:

def percentile(n):
    def percentile_(x):
        return np.percentile(x, n)
    percentile_.__name__ = 'percentile_%s' % n
    return percentile_

然后在agg

中加入此内容
In [11]: column.agg([np.sum, np.mean, np.std, np.median,
                     np.var, np.min, np.max, percentile(50), percentile(95)])
Out[11]:
           sum       mean        std  median          var  amin  amax  percentile_50  percentile_95
AGGREGATE
A          106  35.333333  42.158431      12  1777.333333    10    84             12           76.8
B           36  12.000000   8.888194       9    79.000000     5    22             12           76.8

请注意,这是应该完成的方式......

答案 1 :(得分:11)

更具体地说,如果你只想使用百分位函数聚合你的pandas groupby结果,python lambda函数提供了一个非常简洁的解决方案。使用问题的符号,按百分位数95汇总,应该是:

dataframe.groupby('AGGREGATE').agg(lambda x: np.percentile(x['COL'], q = 95))

您还可以将此函数分配给变量,并将其与其他聚合函数结合使用。

答案 2 :(得分:8)

尝试50%和95%的百分位:

column.describe( percentiles = [ 0.5, 0.95 ] )

答案 3 :(得分:4)

使用 vars <- c("Age", "Smooking", "HTN", "Airway.diseases", "Malignancy", "Bleeding.disorders", "On.anticoagulants_antiplatelets", "Required.ICU.admission", "Classification.of.hemoptysis", "Respiratory.support.", "SOFA.score") out <- lapply(seq_along(vars), function(i){ mtch <- cem(treatment = "TXA", data = Le[,c("TXA", vars[i])], keep.all=TRUE, baseline.group="1", cutpoints=list(SOFA.score=c(0, 4.5, 9.5, 14.5, 19.5))) Le[mtch$matched, c("Record", "TXA", vars[i])]}) names(out) <- vars 方法更有效的解决方案:

pandas.Series.quantile

有几个百分位值

df.groupby("AGGREGATE").agg(("YOUR_COL_NAME", lambda x: x.quantile(0.5))

答案 4 :(得分:1)

您可以让agg()使用自定义函数在指定列上执行:

# 50th Percentile
def q50(x):
            return x.quantile(0.5)

# 90th Percentile
def q90(x):
            return x.quantile(0.9)

my_DataFrame.groupby(['AGGREGATE']).agg({'MY_COLUMN': [q50, q90, 'max']})

答案 5 :(得分:1)

只需将更通用的解决方案引入环。假设您有一个仅包含要分组的一列的DF:

df = pd.DataFrame((('A',10),('A',12),('B',5),('B',9),('A',84),('B',22)), 
                    columns=['My_KEY', 'MY_COL1'])

人们可以使用匿名(lambda)函数列表来汇总和计算基本上任何描述性指标,例如:

df.groupby(['My_KEY']).agg( [np.sum, np.mean, lambda x: np.percentile(x, q=25)] )

但是,如果要聚合多个列,则必须调用一个非匿名函数或显式调用这些列:

df = pd.DataFrame((('A',10,3),('A',12,4),('B',5,6),('B',9,3),('A',84,2),('B',22,1)), 
                    columns=['My_KEY', 'MY_COL1', 'MY_COL2'])

# non-anonymous function
def percentil25 (x): 
    return np.percentile(x, q=25)

# type 1: call for both columns 
df.groupby(['My_KEY']).agg( [np.sum, np.mean, percentil25 ]  )

# type 2: call each column separately
df.groupby(['My_KEY']).agg( {'MY_COL1': [np.sum, np.mean, lambda x: np.percentile(x, q=25)],
                             'MY_COL2': np.size})

答案 6 :(得分:1)

您也可以使用 lambda 来实现相同的目的。一些类似下面的代码:

        agg(
            lambda x: [
                np.min(a=x), 
                np.percentile(q=25,a=x), 
                np.median(a=x), 
                np.percentile(q=75,a=x), 
                np.max(a=x)
    ]
)

答案 7 :(得分:0)

可以如下调用多个函数:

import pandas as pd

import numpy as np

import random

C = ['Ram', 'Ram', 'Shyam', 'Shyam', 'Mahima', 'Ram', 'Ram', 'Shyam', 'Shyam', 'Mahima']

A = [ random.randint(0,100) for i in range(10) ]

B = [ random.randint(0,100) for i in range(10) ]

df = pd.DataFrame({ 'field_A': A, 'field_B': B, 'field_C': C })

print(df)

d = df.groupby('field_C')['field_A'].describe()[['mean', 'count', '25%', '50%', '75%']]
print(d)

我无法在其中调用中位数,但是能够执行其他功能。

答案 8 :(得分:0)

我真的很喜欢the solution Andy Hayden gave,但是,这对我来说有很多问题:

  • 如果数据框具有多个列,它是在列上而不是行上聚合的?
  • 对我来说,行名是percentile_0.5(点而不是下划线)。不知道是什么原因造成的,可能是我在使用Python 3。
  • 还需要导入numpy而不是留在熊猫中(我知道,numpy隐式地导入了熊猫...)

这是一个修复了以下问题的更新版本:

def percentile(n):
    def percentile_(x):
        return x.quantile(0.5)
    percentile_.__name__ = 'percentile_{:2.0f}'.format(n*100)
    return percentile_

答案 9 :(得分:0)

对于您需要的只是describe(通常是最常用的统计信息)的子集的情况,您只需索引返回的熊猫系列即可,而无需任何其他功能。

例如,我通常发现自己只需要显示25,中位数,75和计数即可。只需一行即可完成此操作:

columns.agg('describe')[['25%', '50%', '75%', 'count']]

对于指定一组自己的百分位数,选择答案是一个不错的选择,但是对于简单的用例,不需要额外的功能。

答案 10 :(得分:0)

我相信在大熊猫中惯用的方式是:

df.groupby("AGGREGATE").quantile([0, 0.25, 0.5, 0.75, 0.95, 1])

答案 11 :(得分:0)

df.groupby("AGGREGATE").describe(percentile=[0, 0.25, 0.5, 0.75, 0.95, 1])

默认情况下,describe函数给我们mean, count, std, min, max