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

分组合并DataFrame后去重失败,JSON生成重复数据问题排查

问题描述

有如下两个DataFrame:

DataFrame 1: df1

UniqueIdVendorIdFnameLNameVendorAccNo
00112ABCXYZ8787888
00213XYZFFF8787888
00314PQRZZZ8787888
00516MMMTTT5432100
00617BBBXXX5432100
00718CCCPPP8787888

DataFrame 2: df2

VendorXNoPhNoActiveTypeActiveTime
878788845789YW2019-05-22 09:36:04
878788845789YW2019-05-22 09:36:04
878788812345NM2019-05-23 09:36:04
878788845789YW2019-05-24 09:36:04
878788856742YW2019-05-25 09:36:04
878788845789YH2019-05-26 09:36:04
543210011111YW2019-05-25 09:37:04
543210022222YH2019-05-26 09:38:04

需基于VendorAccNo与VendorXNo关联两个DataFrame生成JSON,同时去除df2中的重复数据。现有实现代码如下:

df_merged = pd.merge(df1, df2, left_on='VendorAccNo', right_on='VendorXNo', how='left')

result = df_merged.groupby(['VendorXNo']).apply(lambda x: x[[
                                'PhNo',
                                'Active',
                                'Type',
                                'ActiveTime']].to_dict('records')).reset_index(name='Phone Info')

uniquedf = ~df_merged['Phone Info'].map(lambda x: tuple(sorted(x.items()))).duplicated()

执行去重代码时报错:

list object has no attribute items

若不添加去重代码,生成的JSON中每个UniqueId对应的Phone Info会重复多次(本该仅5条记录却重复15次),示例如下:

{
"UniqueId" : "001",
"VendorId" : "12",
"Fname"    : "ABC",
"Lname"    : "XYZ",
"VendorAccNo" : "8787888",
"Phone Info" : [
  {
   "PhNo": "45789",
   "Do Not Contact": "Y",
   "Change Date Time": "2019-05-22 09:36:04",
   "Phone Type": "WORK"
  }, 
  // ------ 该记录在每个UniqueId的JSON中重复15次,而正确应为5条记录。
]
}

请问这段代码存在什么问题?为何去重操作会失败?


问题分析与解决方案

代码核心问题

  1. 错误的列访问与类型误解
    Phone Info是result数据框的列,而非df_merged的列——你错误地在df_merged中访问这个不存在的列。退一步说,即使访问result['Phone Info'],每个元素是字典列表,而列表没有items()方法,这就是报错list object has no attribute items的直接原因。

  2. 重复数据的根源:关联前未去重
    df2本身存在完全重复的行(比如前两行),直接merge会让这些重复行与df1中对应VendorAccNo的每一行做笛卡尔积关联,导致数据量大幅膨胀,最终分组后Phone Info里会包含大量重复字典,生成JSON时自然重复多次。

正确实现流程

步骤1:先清理df2的重复数据

从源头消除重复,避免关联时的数据膨胀:

# 去除df2中完全重复的行,保留首次出现的记录
df2_clean = df2.drop_duplicates()

步骤2:关联去重后的df2与df1

用清理后的df2做关联,减少无效行:

df_merged = pd.merge(df1, df2_clean, left_on='VendorAccNo', right_on='VendorXNo', how='left')

步骤3:分组生成结构化的Phone Info

按df1的唯一标识字段分组,确保每个UniqueId对应正确的去重电话记录:

result = df_merged.groupby(['UniqueId', 'VendorId', 'Fname', 'LName', 'VendorAccNo']) \
                  .apply(lambda x: x[['PhNo', 'Active', 'Type', 'ActiveTime']].to_dict('records')) \
                  .reset_index(name='Phone Info')

步骤4:生成目标JSON

将结果转换为JSON格式:

import json
json_output = result.to_json(orient='records', indent=2)
print(json_output)

方案有效性说明

  • 先对df2去重,从根源避免了merge后的笛卡尔积膨胀,减少了不必要的重复行。
  • 分组时包含df1的所有唯一标识字段,确保每个UniqueId对应的Phone Info是该账号下的去重电话记录,不会出现重复多次的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 04:14:53