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

Pandas不使用iterrows按分组列最大值生成时序新行的方法

解决方案

实现思路

借助pandas分组聚合能力替代循环遍历,核心逻辑如下:

  1. 先按球员、赛季年龄排序,保证时序数据顺序正确
  2. 按球员维度分组,筛选出行数≥2的球员(不足2条历史数据无法计算两年平均值,不生成新行)
  3. 取每个球员的最后两行(对应最大的两个赛季年龄,也就是最大年龄往前推两年的数值)计算sa、ga的平均值
  4. 构造新行数据后和原表拼接即可

完整代码

import pandas as pd

# 示例数据
data = [['Adam Wilcox', 8476330, 25, 14.0, 0.0],
        ['Adin Hill', 8478499, 21, 129.0, 14.0],
        ['Adin Hill', 8478499, 22, 322.0, 32.0],
        ['Adin Hill', 8478499, 23, 343.0, 28.0],
        ['Adin Hill', 8478499, 24, 530.0, 46.0],
        ['Adin Hill', 8478499, 25, 237.0, 26.0],
        ['Al Montoya', 8471219, 24, 120.0, 9.0],
        ['Al Montoya', 8471219, 26, 585.0, 46.0],
        ['Al Montoya', 8471219, 27, 832.0, 89.0],
        ['Al Montoya', 8471219, 28, 168.0, 17.0]]

model_df = pd.DataFrame(data, 
                         columns=['player', 'player_id', 'season_age', 'sa', 'ga'])

# 按球员和赛季年龄排序,保证时序正确
model_df = model_df.sort_values(['player', 'player_id', 'season_age']).reset_index(drop=True)

def gen_new_row(group):
    # 不足2条历史数据不生成新行
    if len(group) < 2:
        return pd.Series(dtype='float64')
    # 取最后两年的平均值,转为整数和示例格式对齐
    avg_sa = group['sa'].tail(2).mean().astype(int)
    avg_ga = group['ga'].tail(2).mean().astype(int)
    return pd.Series({
        'player': group['player'].iloc[0],
        'player_id': group['player_id'].iloc[0],
        'season_age': group['season_age'].max() + 1,
        'sa': avg_sa,
        'ga': avg_ga
    })

# 生成新行数据,过滤空行
new_rows = model_df.groupby(['player', 'player_id'], as_index=False).apply(gen_new_row).dropna()

# 拼接原数据和新行
model_df = pd.concat([model_df, new_rows], ignore_index=True)

print(model_df.values.tolist())

代码优势

  • 无需循环遍历,数据量大时性能远高于iterrows实现
  • 自动处理时序排序,避免原表年龄顺序混乱导致的取值错误
  • 自动过滤不足两年数据的球员,鲁棒性更强
  • 代码简洁易维护,符合pandas最佳实践

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 17:54:05