80

我想percentile()通过 pandas 的agg()函数传递 numpy 函数,就像我在下面使用各种其他 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().

这应该怎么做?

4

12 回答 12

122

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

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

请注意确保这是应该如何完成的......

于 2013-07-10T18:51:19.733 回答
50

您可以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']})
于 2019-07-18T06:02:16.917 回答
29

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

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

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

于 2013-11-27T02:55:59.600 回答
17

试试这个 50% 和 95% 的百分位数:

column.describe(percentiles=[0.5, 0.95])
于 2017-10-02T19:39:30.153 回答
14

我真的很喜欢Andy Hayden 给出的解决方案,但是,这对我来说有多个问题:

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

这是修复这些问题的更新版本:

def percentile(n):
    def percentile_(x):
        return x.quantile(n)
    percentile_.__name__ = 'percentile_{:2.0f}'.format(n*100)
    return percentile_
于 2019-02-08T13:13:37.817 回答
13

我相信在 pandas 中这样做的惯用方法是:

df.groupby("AGGREGATE").quantile([0, 0.25, 0.5, 0.75, 0.95, 1])
于 2019-10-29T15:22:25.993 回答
9

对于您只需要一个子集describe(通常是最常见的所需统计信息)的情况,您可以只索引返回的 pandas 系列而不需要任何额外的函数。

例如,我通常发现自己只需要呈现第 25、中位数、第 75 和计数。这可以在一行中完成,如下所示:

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

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

于 2019-05-30T18:08:57.730 回答
6

使用方法更有效的解决方案pandas.Series.quantile

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

有几个百分位值

percentiles = [0.5, 0.9, 0.99]
quantile_funcs = [(p, lambda x: x.quantile(p)) for p in percentiles]
df.groupby("AGGREGATE").agg(quantile_funcs)
于 2021-03-16T16:30:13.233 回答
4
df.groupby("AGGREGATE").describe(percentiles=[0, 0.25, 0.5, 0.75, 0.95, 1])

默认情况下,describe函数给我们mean, count, std, min, max,并且使用百分位数数组,您可以选择所需的百分位数。

于 2019-12-18T16:27:25.517 回答
3

只是为了将更通用的解决方案放入环中。假设您有一个只有一列要分组的 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})
于 2020-03-17T10:47:26.703 回答
3

您也可以使用 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)
    ]
)
于 2021-06-05T07:17:12.620 回答
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)

我无法在此调用中位数,但能够使用其他功能。

于 2018-11-15T06:21:07.427 回答