使用groupby计算球队获胜累计进球时报错TypeError,求原因解析
问题分析与解决
错误原因
你遇到的TypeError: Series.name must be a hashable type错误,根源在于分组时的列选择操作:
- 当你写
data.groupby('Team', group_keys=False)[['Goals','Won']]时,生成的是DataFrameGroupBy对象,每个分组元素是包含两列的DataFrame。 - 在
apply的lambda函数中,(s.Goals*s.Won).cumsum()返回的Series,其name会被pandas自动设置为你选中的列名组成的列表(['Goals','Won'])——而列表属于不可哈希类型,触发了这个错误。
而删除列选择后,data.groupby('Team', group_keys=False)生成的是针对整个DataFrame的GroupBy对象,此时lambda返回的Series的name为可哈希的None,pandas可以正常处理,因此代码能运行。
更高效的实现方案
其实不需要用apply,用groupby+transform或者先计算中间列再累计求和,代码更简洁高效:
data = pd.DataFrame({'Team': ['Italy','Italy','UK','UK','UK'], 'Goals': [2, 2, 1, 4, 1], 'Won': [1, 0, 0, 1, 0]}) # 方案1:分步实现,可读性更强 data['WonGoals'] = data['Goals'] * data['Won'] data['CumulativeGoalsInWonGames'] = data.groupby('Team')['WonGoals'].cumsum() # 方案2:合并为一行代码 # data['CumulativeGoalsInWonGames'] = data.groupby('Team')['Goals'].transform(lambda x: (x * data.loc[x.index, 'Won']).cumsum()) print(data)
运行结果:
Team Goals Won WonGoals CumulativeGoalsInWonGames 0 Italy 2 1 2 2 1 Italy 2 0 0 2 2 UK 1 0 0 0 3 UK 4 1 4 4 4 UK 1 0 0 4
总结
- 避免在仅需单列计算的场景下,分组时选择多列,防止返回的Series出现不可哈希的
name。 - 优先使用
transform替代apply处理分组内的逐行计算,性能和可读性更优。
内容的提问来源于stack exchange,提问作者alepicvs
相关产品推荐
相关产品推荐

