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

DataFrame逐行应用函数异常:全列返回draw问题排查

解决DataFrame每行统计投票结果生成winner列的问题

嘿,我看出来你代码里的问题啦,这两个小错误导致所有结果都是draw:

问题1:对apply的参数理解错了

你写的函数里把x当成了行索引,用new_df.iloc[x]去取整行数据,但实际上当你用apply处理行的时候(需要指定axis=1),传入函数的x是当前行的Series对象,不是行号。而且你原来的调用df['winner_columns'].apply(winner)是在对空列(或已有列)按列处理,完全不是你想要的每行计算逻辑。

问题2:直接取value_counts()的键有风险

如果某行里没有'a'或者'b',直接写value_counts()['a']会抛出KeyError,用get方法设置默认值0会更安全。


修正后的代码

先改函数逻辑,直接对传入的行Series做统计:

def winner(row):
    # 统计当前行中'a'的数量,没有则返回0
    count_a = row.value_counts().get('a', 0)
    # 统计当前行中'b'的数量,没有则返回0
    count_b = row.value_counts().get('b', 0)
    
    if count_a > count_b:
        return 'a'
    elif count_a < count_b:
        return 'b'
    else:
        return 'draw'

然后正确调用apply,指定按行处理(axis=1),并把结果赋值给新列:

# 假设你的原始DataFrame名为df
df['winner_columns'] = df.apply(winner, axis=1)

验证结果

用你给出的示例数据测试,运行后会得到完全符合预期的结果:

vote_1vote_2vote_3vote_4winner_columns
aaaba
bbabb
baabdraw

更简洁的替代方案(无需自定义函数)

如果想少写点代码,也可以用eq和sum直接统计票数,再用lambda判断结果:

# 统计每行a和b的票数
df['count_a'] = df.eq('a').sum(axis=1)
df['count_b'] = df.eq('b').sum(axis=1)

# 生成winner列
df['winner_columns'] = df.apply(
    lambda row: 'a' if row['count_a'] > row['count_b'] 
                else ('b' if row['count_a'] < row['count_b'] else 'draw'),
    axis=1
)

# 可选:删除中间的计数列
df = df.drop(['count_a', 'count_b'], axis=1)

这种方式在数据量较大时,效率可能比自定义函数更高哦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 18:23:10