如何聚合DataFrame并应用Lambda函数实现分组自定义计算
原代码的报错问题拆解
- groupby多列选择语法错误:
groupby('client_name')['price','count','discount']的写法,实际是向groupby对象的列选择方法传入了元组参数,pandas会尝试将该元组作为哈希键匹配列,既无法正确选中目标列,也会导致后续参数解析异常。多列选择必须使用嵌套列表语法,即groupby('client_name')[['price','count','discount']]。 - agg参数规则适配错误:agg方法要求传入的聚合规则为三类:内置聚合函数(如
sum、mean)、可接收分组数据为入参的可调用对象、格式为(自定义输出列名, 待聚合列名, 聚合函数)的元组规则。你直接将全表长度的Series(df['price']*df['count'])作为聚合规则传入,由于Series是可变对象,无法通过哈希校验,因此直接抛出TypeError: 'Series' objects are mutable, thus they cannot be hashed的报错。 - 计算逻辑偏差:需要统计的两个指标都是跨列运算(逐行计算
price*count、再叠加discount折扣)后的聚合结果,并非对单个独立列的直接聚合,这种场景下无法通过直接对列调用内置聚合函数得到正确结果。
单步实现的正确方案
单步完成汇总计算是完全可行的,不需要提前生成临时中间列或中间DataFrame,可直接使用pandas的命名聚合语法实现,示例代码如下:
summary = df.groupby('client_name').agg( **{ # 分组内逐行计算无折扣金额,再求和得到全组总无折扣消费 'Total pre discount': lambda group: (group['price'] * group['count']).sum(), # 分组内逐行计算折后金额,再求和得到全组总折后消费 'Discount applied': lambda group: (group['price'] * group['count'] * group['discount']).sum() } )
上述逻辑的执行流程为:按client_name拆分分组后,将每个分组对应的子数据集传入lambda函数,在函数内部完成跨列乘法计算、组内求和的全流程,直接输出指定列名的汇总DataFrame,全程无额外临时对象生成。
小提示:如果处理十万行以上的大体积数据,组内lambda的运行效率会低于向量化预计算的方案,但后者属于多步实现逻辑,不符合单步操作的需求。
内容的提问来源于stack exchange,提问作者Vahn Toan
相关产品推荐
相关产品推荐

