Pandas Groupby统计异常:user_win_count与user_game_count值相同排查
问题分析与修正方案
嘿,我一眼就揪出问题所在啦!你代码里的user_win_count计算逻辑错了——len(x['result'] == 'Won')根本不是在统计获胜记录数,而是在计算布尔判断后生成的Series的总长度。
错误原因详解
当你执行x['result'] == 'Won'时,pandas会返回一个和当前分组数据行数完全相同的布尔Series(每个元素是True/False,对应该行是否获胜)。而len()函数作用在这个Series上时,只会返回它的总元素数,也就是当前分组的总记录数,这自然就和user_game_count(len(x))的值完全一致了。
修正方法(三种可选)
我给你整理了三种靠谱的修正方式,按需选择:
方法1:用sum()统计True的数量(最简洁)
因为Python里True等价于1,False等价于0,直接对布尔序列求和就能得到获胜记录数:
df_user_data = df.groupby(['user_name']) \ .apply(lambda x: pd.Series( {'user_mean_amount': sum(x['user_amount'])/len(x), 'user_game_count': len(x), 'user_win_count': sum(x['result'] == 'Won') })).reset_index()
方法2:用布尔索引筛选后取长度
先筛选出结果为'Won'的行,再计算长度:
df_user_data = df.groupby(['user_name']) \ .apply(lambda x: pd.Series( {'user_mean_amount': sum(x['user_amount'])/len(x), 'user_game_count': len(x), 'user_win_count': len(x[x['result'] == 'Won']) })).reset_index()
方法3:用value_counts()(兼容无获胜记录的情况)
如果存在某个用户没有任何获胜记录的情况,用value_counts().get('Won', 0)可以避免KeyError,默认返回0:
df_user_data = df.groupby(['user_name']) \ .apply(lambda x: pd.Series( {'user_mean_amount': sum(x['user_amount'])/len(x), 'user_game_count': len(x), 'user_win_count': x['result'].value_counts().get('Won', 0) })).reset_index()
进阶优化:用agg方法更高效
其实pandas的agg方法比apply更高效,代码可读性也更强,推荐你这样写:
df_user_data = df.groupby('user_name').agg( user_mean_amount=('user_amount', 'mean'), # 直接用mean方法替代手动计算 user_game_count=('user_name', 'count'), user_win_count=('result', lambda s: sum(s == 'Won')) ).reset_index()
内容的提问来源于stack exchange,提问作者Edamame
相关产品推荐
相关产品推荐

