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

多人游戏类ELO评分系统:优化Python代码提升运行速度

问题描述

我正在为在线游戏玩家开发类ELO评分系统,ELO原本适用于一对一游戏,现在需要适配多人游戏场景。我用指数函数调整序值范围,给获胜者和名次接近的玩家更高权重。数据里,事件包含event_id(事件ID)和fsize(参赛人数)字段,玩家包含player_id(玩家ID)和finish(名次)字段。当前代码运行结果合理,但处理10万量级的事件数据时速度太慢,希望得到代码优化的帮助。

示例数据集
data_dict = {'event_id': [1,1,1,2,2,2,3,3,3,3,4,4,4,4,4],
        'player_id': [1,2,3,1,2,3,1,2,3,4,1,2,3,4,5],
        'fsize': [3,3,3,3,3,3,4,4,4,4,5,5,5,5,5],
        'finish': [1,2,3,1,2,3,1,2,3,4,1,2,3,4,5]}
df = pd.DataFrame(data_dict)

base = 1.5  # 指数分数的底数,需大于1
# n 是事件中的参赛人数
# 示例:底数1.5、n=3时的指数分数
# np.array([base ** (n - p) - 1 for p in range(1, n + 1)])[0]

print(np.array([base ** (5 - p) - 1 for p in range(1, 5 + 1)])[0])
print(np.array([base ** (5 - p) - 1 for p in range(1, 5 + 1)])[1])
print(np.array([base ** (5 - p) - 1 for p in range(1, 5 + 1)])[2])

# pd.set_option('mode.chained_assignment', None)
df['score'] = 0  # 初始化分数列
for j in range(0, df.shape[0]):   
    df['score'][j] = np.array([base ** (df['fsize'][j] - p) - 1 for p in range(1, df['fsize'][j] + 1)])[df['finish'][j]-1]
    # 归一化分数,使每个event_id下的score总和为1
    df['score_sum'] = df['score'].groupby(df['event_id']).transform('sum')
    df['score_norm'] = round(df.score/df['score_sum'],4)

print(df)
优化后的代码
import pandas as pd
import numpy as np

data_dict = {'event_id': [1,1,1,2,2,2,3,3,3,3,4,4,4,4,4],
        'player_id': [1,2,3,1,2,3,1,2,3,4,1,2,3,4,5],
        'fsize': [3,3,3,3,3,3,4,4,4,4,5,5,5,5,5],
        'finish': [1,2,3,1,2,3,1,2,3,4,1,2,3,4,5]}
df = pd.DataFrame(data_dict)

base = 1.5

# 向量化计算score:直接计算每个玩家对应的指数值,无需生成完整数组再索引
df['score'] = base ** (df['fsize'] - df['finish']) - 1

# 按event_id分组求和,用transform广播到每行
df['score_sum'] = df.groupby('event_id')['score'].transform('sum')

# 归一化并保留4位小数
df['score_norm'] = df['score'] / df['score_sum']
df['score_norm'] = df['score_norm'].round(4)

print(df)
优化说明
  • 向量化替代循环:原代码逐行生成数组再取索引,现在直接利用pandas的列运算,对所有行一次性计算score,速度提升几个数量级。
  • 减少重复计算:原循环里每次都重新计算score_sum,现在只在score计算完成后做一次分组求和,避免冗余操作。
  • 避免链式赋值问题:原代码中df['score'][j]属于链式赋值,可能引发警告或意外行为,优化后直接列赋值更安全高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 21:36:29