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

按多键分组聚合2n个字典列表,实现values值求和合并

按多键分组并求和字典列表中的values值

原始数据

my_list = [
{'metric': {'account': '1', 'email_domain': 'gmail.com', 'version': 'a'}, 
 'values': [[1671256800, '100'], [1671260400, '100']]},
{'metric': {'account': '1', 'email_domain': 'gmail.com', 'version': 'a'}, 
 'values': [[1671256800, '100'], [1671260400, '100']]},
{'metric': {'account': '1', 'email_domain': 'gmail.com', 'version': 'b'}, 
 'values': [[1671256800, '300'], [1671260400, '300']]},
{'metric': {'account': '1', 'email_domain': 'gmail.com', 'version': 'b'}, 
 'values': [[1671256800, '300'], [1671260400, '300']]}]

需求说明

需要按account、email_domain和version三个字段分组,对每组内values中同一时间戳对应的数值求和(数值为字符串类型,求和需先转换为数值类型),最终将结果整理回原字典列表格式。

期望输出

my_list = [
{'metric': {'account': '1', 'email_domain': 'gmail.com', 'version': 'a'}, 
 'values': [[1671256800, '200'], [1671260400, '200']]},
{'metric': {'account': '1', 'email_domain': 'gmail.com', 'version': 'b'}, 
 'values': [[1671256800, '600'], [1671260400, '600']]}]

尝试过的错误代码

曾尝试用Pandas处理,但语法有误:

d = (pd.DataFrame(my_list)).groupby(['metric']['ebs_account'], ['metric']['version']).values.

解决方案

方法一:纯Python实现(无需第三方库)

利用collections.defaultdict进行分组累加,最后重构结果:

from collections import defaultdict

# 初始化分组容器,键为(account, email_domain, version),值为时间戳到累计值的映射
grouped = defaultdict(lambda: defaultdict(int))

for item in my_list:
    metric = item['metric']
    # 生成唯一分组键
    group_key = (metric['account'], metric['email_domain'], metric['version'])
    # 遍历当前项的values,累加对应时间戳的数值
    for timestamp, val_str in item['values']:
        grouped[group_key][timestamp] += int(val_str)

# 转换为目标格式的列表
my_list = []
for (account, email_domain, version), ts_total in grouped.items():
    # 按时间戳排序,保证顺序与原数据一致
    sorted_values = sorted([[ts, str(total)] for ts, total in ts_total.items()], key=lambda x: x[0])
    my_list.append({
        'metric': {
            'account': account,
            'email_domain': email_domain,
            'version': version
        },
        'values': sorted_values
    })

方法二:Pandas实现

通过数据展开、分组求和、重构格式三个步骤完成:

import pandas as pd

# 1. 将原始列表转为DataFrame,并提取metric中的字段
df = pd.DataFrame(my_list)
df[['account', 'email_domain', 'version']] = df['metric'].apply(
    lambda x: pd.Series([x['account'], x['email_domain'], x['version']])
)

# 2. 展开values列,拆分时间戳和数值并转换类型
df = df.explode('values')
df[['timestamp', 'value']] = df['values'].apply(pd.Series)
df['value'] = df['value'].astype(int)

# 3. 分组求和
grouped_df = df.groupby(['account', 'email_domain', 'version', 'timestamp'])['value'].sum().reset_index()

# 4. 重构为目标格式
result = []
for (account, email_domain, version), group in grouped_df.groupby(['account', 'email_domain', 'version']):
    values = group[['timestamp', 'value']].apply(lambda x: [x['timestamp'], str(x['value'])], axis=1).tolist()
    result.append({
        'metric': {
            'account': account,
            'email_domain': email_domain,
            'version': version
        },
        'values': values
    })

my_list = result

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:10:24