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

复刻pandas groupby实现字典分组,寻求性能优化并对比pandas效率

字典分组优化与效率对比建议

问题背景

给定字典d(各键对应列表长度一致,且d['A']已按升序排列),需按指定键'A'执行分组操作,生成双层字典。输入示例:

d = { 'A' : [0, 0, 1, 1], 'B' : [1, 2, 4, 3], 'C' : [None, 0, None, 1] }

期望输出:

dd[0] = {'B' : [1, 2], 'C' : [None, 0]}
dd[1] = {'B' : [4, 3], 'C' : [None, 1]}

实际场景中字典包含36个键,每个键对应约10^6个元素,需优化分组方法(如多进程),同时对比现有自定义方法与pandas等价实现的执行效率。


现有实现的问题与修正

1. 自定义实现的逻辑缺陷

原自定义代码使用集合推导生成结果,会导致输出结构不符合预期,且存在不必要的集合转换开销,修正后的代码如下:

from collections import defaultdict

def dict_groupby(d, key):
    grouped = defaultdict(list)
    # 预计算非分组键,避免循环内重复计算
    other_keys = [k for k in d if k != key]
    for i, v in enumerate(d[key]):
        # 改用字典推导生成对应键值对
        grouped[v].append({k: d[k][i] for k in other_keys})
    return dict(grouped)

dd = dict_groupby(d, 'A')
print(dd)

2. pandas实现的补充说明

原pandas代码生成的是{分组键: 子DataFrame}的结构,若要转换为目标双层字典,需额外处理:

import pandas as pd
from itertools import chain

# 将字典转为DataFrame
df = pd.DataFrame(d)
grouped = df.groupby('A')
# 转换为嵌套列表的字典结构
dd = {k: v.to_dict('list') for k, v in grouped}
print(dd)

优化方案与效率分析

1. 利用有序分组的批量切片优化(推荐)

由于d['A']已升序排列,无需逐个元素遍历分组,可直接定位每个分组的起止索引,批量切片生成子列表,大幅降低循环次数:

def optimized_dict_groupby(d, key):
    # 定位所有分组的起止索引
    groups = []
    a_vals = d[key]
    current_val = a_vals[0]
    start_idx = 0
    for idx in range(1, len(a_vals)):
        if a_vals[idx] != current_val:
            groups.append((current_val, start_idx, idx))
            current_val = a_vals[idx]
            start_idx = idx
    groups.append((current_val, start_idx, len(a_vals)))
    
    # 批量切片生成结果
    other_keys = [k for k in d if k != key]
    result = {}
    for val, start, end in groups:
        result[val] = {k: d[k][start:end] for k in other_keys}
    return result

优势:遍历次数从106次降至分组数(远小于106),内存开销低(Python切片为浅拷贝,无需复制大量元素),性能比原自定义实现提升数倍。

2. 多进程优化的适用性分析

本场景属于内存/IO密集型任务,多进程会带来进程间数据传输的额外开销(如大列表的跨进程复制),反而可能降低效率。仅当分组数极多且单个分组数据量极大时,可尝试按分组拆分任务,使用multiprocessing.Pool处理,但收益有限,不推荐作为首选方案。

3. 与pandas实现的效率对比

  • 性能:pandas的groupby基于C扩展实现,10^6行数据下,纯计算速度略优于优化后的自定义实现,但字典转DataFrame、DataFrame转字典的步骤会产生额外开销。
  • 内存:pandas会将数据转为二维数组存储,36列×10^6行的场景下,内存占用远高于纯字典实现。
  • 结论:内存充足时选pandas追求极致性能;内存紧张时,优化后的自定义实现是更优选择。

4. 其他细节优化

  • 提前预计算other_keys,避免循环内重复遍历字典键
  • 对于超大规模数据,可改用numpy数组存储,切片和分组操作的效率会进一步提升

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 04:42:53