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

如何加速DataFrame循环?90万条数据的向量化优化方法

问题描述

需要处理90万条数据,希望加速DataFrame中的循环操作。需求是为DataFrame新增名为Count的列,统计同一player中score小于当前行target score的次数(每行的target score不同)。

输入示例

index Nom player  score  target score
0      0      felix      3            10
1      1      felix      8             7
2      2       theo      4             5
3      3    patrick     12             6
4      4     sophie      7             6
5      5     sophie      3             6
6      6      felix      2             4
7      7      felix      2             2
8      8      felix      2             3

预期输出

index Nom player  score  target score  Count
0      0      felix      3            10      5
1      1      felix      8             7      4
2      2       theo      4             5      1
3      3    patrick     12             6      0
4      4     sophie      7             6      1
5      5     sophie      3             6      1
6      6      felix      2             4      4
7      7      felix      2             2      0
8      8      felix      2             3      3

当前低效代码

df2 = df.copy()
df2['Count']= [np.count_nonzero((df.values[:,1] == row[2] )& ( df.values[:,2] < row[4]) )    for row in df.itertuples()]
print(df2)

询问是否可以通过向量化优化该计算,以及具体实现方法。


向量化优化方案

当然可以通过向量化操作大幅提升效率,核心思路是分组排序+二分查找,将原O(n²)的逐行循环优化为O(n log k)的高效计算(k为每个player组的大小),完全适配90万条数据的场景。

实现方式1:分组预排序 + 逐行查找

import pandas as pd
import numpy as np

# 预先生成每个player对应的排序后score数组
sorted_score_map = df.groupby('player')['score'].apply(np.sort)

# 定义查找函数:在对应player的排序数组中,用二分查找统计小于target的元素数
def calc_count(row):
    return np.searchsorted(sorted_score_map[row['player']], row['target score'], side='left')

# 批量计算Count列
df['Count'] = df.apply(calc_count, axis=1)

实现方式2:分组批量处理(更高效)

这种方式直接在分组内批量处理所有行,避免逐行apply的开销:

import pandas as pd
import numpy as np

# 分组后对每个组内的score排序,再批量用二分查找匹配target score
counts = df.groupby('player').apply(
    lambda group: np.searchsorted(np.sort(group['score']), group['target score'], side='left')
)

# 将分组结果展开并赋值回原DataFrame
df['Count'] = counts.explode().values

效率说明

  • 原代码的逐行循环会对每行遍历整个DataFrame,数据量越大效率越低;优化后的方案利用numpy的二分查找(底层C实现)和pandas的分组操作,将时间复杂度从O(n²)降到O(n log k),90万条数据的处理速度会有数量级的提升。
  • np.searchsorted的side='left'参数确保返回第一个大于等于目标值的位置,这个位置的索引恰好是数组中小于目标值的元素总数,完全符合需求。

内容的提问来源于stack exchange,提问作者Félix Le Besnerais

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 21:25:34