【问题标题】:Pandas groupby quantile valuesPandas groupby 分位数值
【发布时间】:2022-02-10 08:48:26
【问题描述】:

我尝试从数据框中计算特定的分位数值,如下面的代码所示。分行计算没有问题。

尝试运行最后两行时,我收到以下错误:

AttributeError: 'SeriesGroupBy' object has no attribute 'quantile(0.25)'

我该如何解决这个问题?

import pandas as pd
df = pd.DataFrame(
    {
        'x': [0, 1, 0, 1, 0, 1, 0, 1],
        'y': [7, 6, 5, 4, 3, 2, 1, 0],
        'number': [25000, 35000, 45000, 50000, 60000, 70000, 65000, 36000]
    }
)
f = {'number': ['median', 'std', 'quantile']}
df1 = df.groupby('x').agg(f)
df.groupby('x').quantile(0.25)
df.groupby('x').quantile(0.75)

# code below with problem:
f = {'number': ['median', 'std', 'quantile(0.25)', 'quantile(0.75)']}
df1 = df.groupby('x').agg(f)

【问题讨论】:

标签: python pandas


【解决方案1】:

我更喜欢 def 函数

def q1(x):
    return x.quantile(0.25)

def q3(x):
    return x.quantile(0.75)

f = {'number': ['median', 'std', q1, q3]}
df1 = df.groupby('x').agg(f)
df1
Out[1643]: 
  number                            
  median           std     q1     q3
x                                   
0  52500  17969.882211  40000  61250
1  43000  16337.584481  35750  55000

【讨论】:

  • 我试过 lambda 没有工作想到你已经发布的功能
  • 不,因为 lambda 将返回一个列名 lambda 它会导致规范错误。想知道你是怎么做到的
  • @Dark 类似于 fl = lambda x : x.quantile(0.25) fl.__name__ = 'f1'
  • 我的意思是这个 f = {'number': ['median', 'std', lambda x: x.quantile(0.25), lambda x: x.quantile(0.75)]} ,当然没想过分配给变量。
  • @Dark 这个不行,返回重复的 lambda 名称 :-),你是对的
【解决方案2】:

@WeNYoBen 的回答很棒。但是有一个限制,那就是需要为每个分位数创建一个新函数。如果分位数变大,这可能是一个非常不合常理的练习。更好的方法是使用函数来创建函数,并适当地重命名该函数。

def rename(newname):
    def decorator(f):
        f.__name__ = newname
        return f
    return decorator

def q_at(y):
    @rename(f'q{y:0.2f}')
    def q(x):
        return x.quantile(y)
    return q

f = {'number': ['median', 'std', q_at(0.25) ,q_at(0.75)]}
df1 = df.groupby('x').agg(f)
df1

Out[]:
number                            
  median           std  q0.25  q0.75
x                                   
0  52500  17969.882211  40000  61250
1  43000  16337.584481  35750  55000

rename 装饰器对函数进行重命名,以便 pandas agg 函数可以处理返回的分位数函数的重用(否则所有分位数结果都会出现在名为 q 的列中)。

【讨论】:

  • 不错!不过,不需要装饰器:您可以在从 q_at 返回之前重命名 q
【解决方案3】:

如果您想为聚合列命名,有一个很好的方法:

df1.groupby('x').agg(
    q1_foo=pd.NamedAgg('number', q1),
    q2_foo=pd.NamedAgg('number', q2)
)

其中q1q2 是函数。

甚至更简单:

df1.groupby('x').agg(
    q1_foo=('number', q1),
    q2_foo=('number', q2)
)

【讨论】:

    猜你喜欢
    • 2019-08-05
    • 2018-03-10
    • 2019-02-24
    • 1970-01-01
    • 2014-07-29
    • 1970-01-01
    • 2018-10-02
    • 1970-01-01
    • 2017-01-07
    相关资源
    最近更新 更多