You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas自定义函数在groupby apply/agg中报错:numpy.float64不可调用

解决按分组计算加权平均值的apply/agg报错问题

错误原因分析

第一个错误:'numpy.float64' object is not callable

你调用apply(avg_w(df))时,直接执行了avg_w(df)并将结果(一个numpy.float64数值)传给了apply,但apply需要接收的是函数对象(即函数名本身,不要加括号调用),而非已经计算出的数值。这就导致Python试图把一个数值当作函数来执行,因此抛出“不可调用”的错误。

第二个错误:TypeError: unhashable type: 'dict'

你修改后的apply({'avgw': [avg_w2(dt)]})存在两个问题:

  1. apply不支持这种字典格式的参数(这类格式是agg方法的用法);
  2. 同样犯了直接调用函数的错误:avg_w2(dt)会立即执行并返回结果,而非传递函数对象。

正确解决方案

方案1:使用apply传递函数对象(最简方式)

你的第一个函数avg_w逻辑是正确的,只需修正apply的调用方式,直接传递函数名即可:

import pandas as pd
import numpy as np

df = pd.DataFrame([['RETIRO', 65, 1, 10.7],
                   ['SAN NICOLAS',116, 1, 23.2],
                   ['RETIRO', 101, 2, 28.7],
                   ['FLORES', 136 , 2, 23.5]],
                  columns=['BARRIO', 'HOGARES', 'COMUNA', 'NSE'])

def avg_w(dt):
    return np.average(a = dt.NSE, weights = dt.HOGARES)

# 正确调用:传递函数对象,而非执行结果
result = df.loc[:,['COMUNA','NSE','HOGARES']].groupby(['COMUNA']).apply(avg_w)
print(result)

输出结果:

COMUNA
1    18.710994
2    25.716034
dtype: float64

方案2:返回Series以得到DataFrame格式结果

如果希望返回结构更清晰的DataFrame,可以修改函数返回pd.Series,再配合apply:

def avg_w2(dt):
    return pd.Series({'weighted_avg_NSE': np.average(dt.NSE, weights=dt.HOGARES)})

result = df.groupby(['COMUNA']).apply(avg_w2)
print(result)

输出结果:

weighted_avg_NSE
COMUNA                   
1               18.710994
2               25.716034

方案3:使用agg结合lambda函数(无需自定义函数)

可以直接用agg方法配合lambda表达式,更简洁地实现需求:

result = df.groupby(['COMUNA']).agg(
    weighted_avg_NSE=lambda x: np.average(x['NSE'], weights=x['HOGARES'])
)
print(result)

输出结果与方案2一致。


内容的提问来源于stack exchange,提问作者flora93

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 15:50:25