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

pandas去重失败 嵌套JSON扁平化后前3列数据仍重复问题

Pandas展平嵌套JSON时去重失效问题排查

问题描述

使用pandas移除嵌套数据集中的重复字段时,现有代码输出结果仍存在重复,调用drop_duplicates()方法无法正常去除重复项,需要确认是展平逻辑错误还是处理流程设计冗余。

  • 异常表现:导出的CSV结果中,前3列(codeId、日期、收益率)始终存在重复,其余属性列无重复问题。
    处理后结果截图

待处理原始数据

{
  "codeId": "fc-5599",
  "financeInfo": [
    {
      "date": "2022-01-30",
      "totalReturn": 0.022425456852
    },
    {
      "date": "2022-01-30",
      "totalReturn": 0.022425456852
    },
    {
      "date": "2022-01-30",
      "totalReturn": 0.022425456852
    },
    {
      "date": "2022-01-30",
      "totalReturn": 0.022425456852
    },
    {
      "date": "2022-01-30",
      "totalReturn": 0.022425456852
    }, 
    {
      "date": "2022-02-28",
       "totalReturn": -0.0424735070051586,
       "financeInfoAttributes": [
       {
         "attributeId": "a-256",
         "value": "12.032791372796499"
       },
       {
       "attributeId": "a-257",
       "value": "9.975964795996589"
       },
       {
       "attributeId": "a-258",
       "value": "4.719852927810759"
       },
       {
       "attributeId": "a-259",
       "value": "4.18144793134823"
       }     
    ]
    }
  ]
}

当前处理代码

items = []
for i in response_finance['results']:
    items.append(i)

df = pd.DataFrame(items)

df1 = df.loc[:, ['codeId', 'financeInfo']]
for i in df1.columns:
    df1 = df1.explode(i)

flat_df1 = pd.json_normalize(json.loads(df1.to_json(orient="records")))

df2 = flat_df1.loc[:, ['codeId', 'financeInfo.date',
                       'financeInfo.totalReturn', 'financeInfo.financeInfoAttributes']]
for i in df2.columns:
    df2 = df2.explode(i)

flat_df2 = pd.json_normalize(json.loads(df2.to_json(orient="records")))

result = pd.DataFrame(flat_df2)

result.drop_duplicates(subset=None, inplace=True)

result.to_csv('data.csv', index=True)

问题根因

  1. 原始数据自带重复:源数据的financeInfo数组中本身就存在5条完全一致的2022-01-30收益记录,这是重复的基础来源。
  2. 去重逻辑默认特性导致失效:2022-01-30的记录没有financeInfoAttributes字段,展平后对应位置为NaN值。pandas默认判定NaN != NaN,因此drop_duplicates()会把带有NaN、其余字段完全一致的行判定为不重复,无法完成去重。
  3. 处理流程存在冗余设计:
    • 循环对所有列执行explode没有必要,仅对存储数组/列表的列执行explode即可,对字符串、数值这类标量列explode属于无效操作。
    • 多次执行to_json->json.loads->json_normalize的转换链完全多余,徒增性能消耗和类型转换异常风险。

修正方案

直接用json_normalize按层级展平数据,仅对数组列做explode,去重时将NaN统一处理为相同占位符即可,优化后代码如下:

import pandas as pd
import json

# 直接展平第一层嵌套,指定记录路径和保留的顶层字段
df = pd.json_normalize(
    response_finance['results'],
    record_path='financeInfo',
    meta=['codeId'],
    errors='ignore'
)
# 仅对存储属性数组的列做explode
df = df.explode('financeInfoAttributes', ignore_index=True)
# 展平内层属性字段
flat_df = pd.json_normalize(
    df['financeInfoAttributes'].fillna({}).to_list()
).add_prefix('financeInfoAttributes.')
# 合并所有字段
result = pd.concat([df.drop(columns=['financeInfoAttributes']), flat_df], axis=1)
# 临时填充NaN为统一占位符完成去重,之后还原空值
result = result.fillna('__NAN_PLACEHOLDER__').drop_duplicates(keep='first').replace('__NAN_PLACEHOLDER__', pd.NA)

result.to_csv('data.csv', index=False)

处理后1月30日的重复记录只会保留1条,2月28日的4条属性记录正常保留,无多余重复。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:36:21