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

如何向量化复杂累积聚合问题以高效处理万亿级数据?

向量化实现基于累积阈值的分组bar_index生成

需求概述

按identifier和date字段分组,以阈值τ=10为依据生成bar_index,规则如下:

  • 组内累积值达到或超过阈值时,当前及之前未完成累积的所有条目归为同一bar_index,随后重置累积值开启新分组
  • 若单条记录的value直接超过阈值,该记录单独作为一个分组

现有非向量化循环代码可实现需求,但无法支撑万亿级规模数据的处理,需通过向量化方法优化执行效率。

示例数据集

先构造测试用数据集:

import pandas as pd
import numpy as np

data = pd.DataFrame({
    'identifier': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B'],
    'date': pd.date_range('2023-01-01', periods=8).tolist(),
    'value': [3, 4, 5, 12, 6, 7, 2, 15]
})

现有循环实现代码

def generate_bar_index(df, threshold=10):
    df = df.sort_values(['identifier', 'date']).reset_index(drop=True)
    df['bar_index'] = 0
    current_id = None
    current_cum = 0
    current_bar = 0
    
    for idx, row in df.iterrows():
        if row['identifier'] != current_id:
            current_id = row['identifier']
            current_cum = 0
            current_bar = 1
        else:
            current_bar = df.loc[idx-1, 'bar_index']
        
        if row['value'] >= threshold:
            df.loc[idx, 'bar_index'] = current_bar
            current_cum = 0
            current_bar += 1
        else:
            current_cum += row['value']
            df.loc[idx, 'bar_index'] = current_bar
            if current_cum >= threshold:
                current_cum = 0
                current_bar += 1
    return df

# 测试执行
result_loop = generate_bar_index(data)
print(result_loop)

向量化优化方案

以下实现通过分组内的批量计算替代逐行循环,利用pandas和numpy的向量化特性提升效率,可支持大规模数据处理:

def generate_bar_index_vectorized(df, threshold=10):
    # 先按分组键排序,确保顺序正确
    df = df.sort_values(['identifier', 'date']).reset_index(drop=True)
    
    def process_group(group):
        vals = group['value'].values
        n = len(vals)
        # 标记单条值超阈值的记录
        single_over = vals >= threshold
        # 初始化累积值和分组起始标记
        current_cum = 0
        start_new_group = np.zeros(n, dtype=bool)
        start_new_group[0] = True
        
        for i in range(1, n):
            # 前一条是单条超阈值,当前条开启新分组
            if single_over[i-1]:
                start_new_group[i] = True
                current_cum = 0
                continue
            
            # 当前条是单条超阈值,自身开启新分组
            if single_over[i]:
                start_new_group[i] = True
                current_cum = 0
                continue
            
            # 累积值计算,达标则开启新分组
            current_cum += vals[i]
            if current_cum >= threshold:
                start_new_group[i] = True
                current_cum = 0
        
        # 计算bar_index:分组起始标记的累积和
        group['bar_index'] = start_new_group.cumsum()
        return group
    
    # 分组应用处理逻辑
    df = df.groupby('identifier', group_keys=False).apply(process_group)
    return df

# 测试执行
result_vectorized = generate_bar_index_vectorized(data)
print(result_vectorized)

方案说明

  • 该实现将循环限制在分组内部,避免了全局逐行循环的低效问题
  • 利用numpy数组进行批量标记和计算,大幅降低Python层面的循环开销
  • 核心逻辑通过start_new_group标记每个新分组的起始位置,最终通过累积和生成bar_index

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 14:14:50