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

如何编写Python函数动态计算Pandas DataFrame的玩家筹码(stack)?

问题描述

现有如下示例DataFrame:

handplayereventamountstack_size
#345pairedwin144552
#345pairedbet returned72552
#345pairedbets72552
#345pairedbets43552
#345pairedraises18552
#345pairedstack0552
#345pairedstarting hand00

需要按照以下逻辑动态计算result列:

  • 若event属于('bets', 'calls', 'big blind', 'small blind', 'raises'):首次计算用stack_size减去amount;后续同类型事件用上一行的result值减去当前行的amount
  • 若event属于('bet returned', 'win'):用上一行的result值加上当前行的amount
  • 所有操作需在hand和player分组内执行

编写的函数仅考虑当前行,无法得到期望输出:

import pandas as pd

data = {'hand': ['#345', '#345', '#345', '#345', '#345', '#345', '#345'],
        'player': ['paired', 'paired', 'paired', 'paired', 'paired', 'paired', 'paired'],
        'event': ['win', 'bet returned', 'bets', 'bets', 'raises', 'stack', 'starting hand'],
        'amount': [144, 72, 72, 43, 18, 0, 0],
        'stack_size': [552, 552, 552, 552, 552, 552, 0]}
df = pd.DataFrame(data)

def adjust_stack(row):
    if row['event'] in (
        'bets', 'calls', 'big blind',
        'small blind', 'raises'
    ):
        return row['stack_size'] - row['amount']
    elif row['event'] in ('bet_returned', 'win'):
        return row['stack_size'] + row['amount']
    else:
        return row['stack_size']

df.assign(
    result = df.apply(adjust_stack, axis=1)
).query('hand=="#345" and player=="paired"')

期望的正确输出:

handplayereventamountstack_sizeresult
#345pairedwin144552635
#345pairedbet returned72552491
#345pairedbets72552419
#345pairedbets43552491
#345pairedraises18552534
#345pairedstack0552
#345pairedstarting hand00
解决方案

问题核心是需要逐行累积计算,而不是仅依赖当前行数据。可以用groupby结合自定义累积函数实现:

import pandas as pd

data = {'hand': ['#345', '#345', '#345', '#345', '#345', '#345', '#345'],
        'player': ['paired', 'paired', 'paired', 'paired', 'paired', 'paired', 'paired'],
        'event': ['win', 'bet returned', 'bets', 'bets', 'raises', 'stack', 'starting hand'],
        'amount': [144, 72, 72, 43, 18, 0, 0],
        'stack_size': [552, 552, 552, 552, 552, 552, 0]}
df = pd.DataFrame(data)

def calculate_result(group):
    result = []
    prev_val = None
    for idx, row in group.iterrows():
        event = row['event']
        amount = row['amount']
        stack_size = row['stack_size']
        
        # 跳过不需要计算的事件
        if event in ('stack', 'starting hand'):
            result.append(None)
            continue
        
        # 初始化首次计算值
        if prev_val is None:
            if event in ('bets', 'calls', 'big blind', 'small blind', 'raises'):
                current_val = stack_size - amount
            elif event in ('bet returned', 'win'):
                current_val = stack_size + amount
        else:
            # 基于上一行结果计算当前值
            if event in ('bets', 'calls', 'big blind', 'small blind', 'raises'):
                current_val = prev_val - amount
            elif event in ('bet returned', 'win'):
                current_val = prev_val + amount
        
        result.append(current_val)
        prev_val = current_val
    
    group['result'] = result
    return group

# 按hand和player分组执行计算
df = df.groupby(['hand', 'player'], group_keys=False).apply(calculate_result)

print(df)

代码说明

  1. 分组隔离:通过groupby(['hand', 'player'])确保每个玩家每手牌的计算独立进行,互不干扰
  2. 逐行累积:遍历每组内的每一行,维护上一行的result值(prev_val),根据当前事件类型更新当前值
  3. 特殊事件处理:对stack和starting hand直接返回空值,不参与累积计算

运行后即可得到符合期望的result列。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 06:28:11