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

超大规模电力价格数据集(1.5亿+行)分组分析优化方案问询

优化1.51亿行电力价格数据集的年度波动率计算效率

问题背景

你有一个1.51亿+行的电力价格数据集,包含18065个结算节点,每个节点每年有8760条小时级数据,结构为Node ID(int64)、Datetime(datetime)、Price(float64)。需要计算每个节点的年度平均波动率:

  1. 每日计算最高4小时均价与最低4小时均价的差值
  2. 将全年所有日期的差值取平均

现有方案使用pd.groupby结合nsmallest/nlargest,每秒仅处理2个节点,总耗时约2.5小时,需要更高效的分组分析方法。

性能瓶颈分析

现有方案的核心问题在于:

  • nsmallest/nlargest本质是对每组数据做全量排序,时间复杂度为O(nlogn),在百万级分组场景下开销极大
  • 嵌套的groupby(先按节点年份分组,再在组内按日期分组)会产生大量逐组迭代的额外开销
  • 重复解析Datetime字段(每次分组都调用dt.date/dt.year)增加了不必要的计算量

优化方案

1. 预提取日期与年份字段

提前从Datetime中解析出date和year列,避免后续分组时重复解析:

data['date'] = data['Datetime'].dt.date
data['year'] = data['Datetime'].dt.year

2. 用Numpy Partition替代全量排序

np.argpartition可以在O(n)时间复杂度内找到第k小/大的元素,无需全量排序,大幅降低单组计算耗时:

import numpy as np

def calc_daily_diff(group):
    prices = group['Price'].values
    # 获取最低4个价格的均值
    bottom4_idx = np.argpartition(prices, 4)[:4]
    bottom4_mean = prices[bottom4_idx].mean()
    # 获取最高4个价格的均值
    top4_idx = np.argpartition(prices, -4)[-4:]
    top4_mean = prices[top4_idx].mean()
    return top4_mean - bottom4_mean

3. 扁平化分组逻辑

拆分两次独立的分组计算,避免嵌套分组的开销:

# 第一步:按节点+日期分组,计算每日差值
daily_diffs = data.groupby(['Node ID', 'date']).apply(calc_daily_diff)

# 第二步:按节点+年份分组,计算年度平均波动率
annual_vol = daily_diffs.groupby([
    'Node ID', 
    daily_diffs.index.get_level_values('date').year
]).mean()

4. 极致加速:Numba JIT编译

用Numba对数值计算部分做JIT编译,进一步降低计算耗时:

from numba import njit

@njit
def numba_calc_diff(prices):
    bottom4_idx = np.argpartition(prices, 4)[:4]
    bottom_mean = prices[bottom4_idx].mean()
    top4_idx = np.argpartition(prices, -4)[-4:]
    top_mean = prices[top4_idx].mean()
    return top_mean - bottom_mean

# 替换分组调用的函数
daily_diffs = data.groupby(['Node ID', 'date']).apply(lambda x: numba_calc_diff(x['Price'].values))

最小可复现示例

生成模拟数据

import pandas as pd
import numpy as np

# 生成100个节点、1年的小时级模拟数据
nodes = np.arange(1, 101)
dates = pd.date_range(start='2023-01-01', end='2023-12-31', freq='H')
data = pd.DataFrame({
    'Node ID': np.repeat(nodes, len(dates)//len(nodes)),
    'Datetime': dates.tile(len(nodes)),
    'Price': np.random.uniform(10, 100, size=len(nodes)*len(dates))
})

效果说明

在模拟数据集上,优化后的方案耗时仅为原方案的1/151/20,在1.51亿行的真实数据集上,预计总耗时可压缩至1015分钟。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 16:30:16