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

如何将DataFrameGroupBy对象转换为不含索引列的指定结构字典

问题描述

需要对如下DataFrame执行groupby操作:

VendorID  ProductID  Qty     Expiring   Date
    123456    P789456     1195    True       xyz
    123456    P123456     1015    True       xyz
    987564    P168816     251     False      xyz
    123456    P900456     1222    True       xyz

期望得到不含索引列的指定结构字典:

[
   {
      'vendorid': 123456,
      'products': [
                      {'productid': 'P789456', 'qty': 1195},
                      {'productid': 'P123456', 'qty': 1015},
                      {'productid': 'P900456', 'qty': 1222}
                   ],
      'expiring': True,
      'date': 'xyz'
   },
   {
      'vendorid': 987564,
      'products': [
                      {'productid': 'P168816', 'qty': 251},
                   ],
      'expiring': False,
      'date': 'xyz'
   }
]

尝试以下代码时报错:

df = df.groupby('vendorid')[['productid', 'qty', 'expiring', 'date']]

df = df.apply(lambda x: x.set_index('productid').to_dict(orient='index')).to_dict()
解决思路与代码

原代码问题分析

  1. 列名不匹配:原DataFrame列名是大写(VendorID、ProductID等),代码中用小写列名会直接触发KeyError,这是报错的核心原因。
  2. 结构逻辑错误:set_index('productid').to_dict(orient='index')会生成以产品ID为键的字典结构,和期望的数组格式完全不符。

正确实现方案

方案一:循环分组处理

# 先统一列名为小写,匹配目标字典的键名
df.columns = df.columns.str.lower()

result = []
# 按vendorid分组遍历
for vendor_id, group in df.groupby('vendorid'):
    # 提取每组的expiring和date(假设同一供应商下这两个值唯一)
    expiring_status = group['expiring'].iloc[0]
    record_date = group['date'].iloc[0]
    # 直接将productid和qty转换为目标列表结构
    product_list = group[['productid', 'qty']].to_dict('records')
    # 组合成目标字典并加入结果列表
    result.append({
        'vendorid': vendor_id,
        'products': product_list,
        'expiring': expiring_status,
        'date': record_date
    })

print(result)

方案二:用groupby.apply简化实现

df.columns = df.columns.str.lower()

result = (df.groupby('vendorid')
          .apply(lambda g: {
              'vendorid': g.name,  # g.name就是当前分组的vendorid值
              'products': g[['productid', 'qty']].to_dict('records'),
              'expiring': g['expiring'].iloc[0],
              'date': g['date'].iloc[0]
          })
          .tolist())  # 将分组结果转为列表

print(result)

关键说明

  • 列名统一:把原DataFrame的大写列名转为小写,避免键名匹配错误。
  • to_dict('records'):这个参数会将DataFrame的每一行转换为一个字典,直接生成products需要的列表结构,无需手动拼接。
  • 唯一值提取:假设同一供应商的expiring和date值唯一,因此用iloc[0]取第一个值;如果存在多值情况,需要额外处理(比如取唯一值或抛出异常)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 21:12:30