基于NumPy并行计算足球队净胜场(胜场-负场)
无循环并行计算净胜场方案(NumPy + PyTorch)
NumPy实现
核心思路
利用np.add.at实现索引原地累加,该函数会对每个索引的所有出现次数进行累加,解决普通索引赋值时重复索引被覆盖的问题。
代码示例
import numpy as np # 模拟数据:20场比赛,10支球队(ID 0-9,若为1-10则X初始化长度为11) match = np.random.randint(0, 10, size=(20, 2)) outcome = np.random.choice([1, -1], size=(20, 1)) # 初始化净胜场数组 X = np.zeros(10, dtype=int) # 扩展结果数组:每一行对应两个球队的增减量(胜队+1,负队-1) outcome_expanded = np.concatenate([outcome, -outcome], axis=1) # 无循环并行累加 np.add.at(X, match, outcome_expanded)
扩展至多球员场景
若每个队有N名球员,需计算每位球员的净胜场(与球队净胜场一致),只需将X改为二维数组,np.add.at会自动广播实现累加:
num_players_per_team = 5 X_players = np.zeros((10, num_players_per_team), dtype=int) # 扩展结果数组适配球员维度,并行累加 np.add.at(X_players, match, outcome_expanded[:, :, np.newaxis])
PyTorch实现
对应PyTorch中使用torch.scatter_add_实现相同的并行累加逻辑,适合机器学习架构中的GPU并行计算:
基础场景代码
import torch # 模拟张量数据 match = torch.randint(0, 10, (20, 2)) outcome = torch.tensor(np.random.choice([1, -1], size=(20,1)), dtype=torch.int) outcome_expanded = torch.cat([outcome, -outcome], dim=1) # 初始化净胜场张量 X = torch.zeros(10, dtype=torch.int) # 展平索引与结果数组,执行并行累加 X.scatter_add_(0, match.flatten(), outcome_expanded.flatten())
扩展至多球员场景
num_players_per_team = 5 X_players = torch.zeros(10, num_players_per_team, dtype=torch.int) # 扩展维度适配球员数量,并行累加 X_players.scatter_add_( 0, match[..., None].expand(-1, -1, num_players_per_team), outcome_expanded[..., None] )
关键说明
- 普通的
X[match] += outcome_expanded无法得到正确结果,因为重复索引的累加会被覆盖,而np.add.at/torch.scatter_add_会对每个索引的所有出现次数进行累加。 - 上述方案完全并行,无循环,可无缝扩展到任意数量的球队、比赛或球员规模。
内容的提问来源于stack exchange,提问作者Loua
相关产品推荐
相关产品推荐

