如何拆分Pandas DataFrame中两个长度可变的嵌套列
解决方案:拆分多列字典列表为独立行(避免重复)
针对你遇到的问题,核心是规避同时explode多列导致的笛卡尔积重复,正确思路是分别处理payments和ledger_account_bookings两列,生成两个独立的子DataFrame后再合并,确保每条支付记录、分类账记录各自占一行。
步骤说明&代码实现
假设你的原始DataFrame名为df_financial_mutations,包含transaction_id、total_amount、date、payments、ledger_account_bookings字段:
- 处理
payments列
import pandas as pd from pandas import json_normalize # 提取基础字段 + payments列 df_payments = df_financial_mutations[['transaction_id', 'total_amount', 'date', 'payments']].copy() # 拆分payments列表为单独行,空列表转为NaN后后续过滤 df_payments = df_payments.explode('payments', ignore_index=True) # 过滤无支付记录的行 df_payments = df_payments.dropna(subset=['payments']) # 展开字典为独立列并添加前缀 df_payments_normalized = json_normalize(df_payments['payments']).add_prefix('payments_') # 合并基础字段与展开后的支付字段 df_payments_final = pd.concat([df_payments.drop('payments', axis=1), df_payments_normalized], axis=1)
- 处理
ledger_account_bookings列
# 提取基础字段 + ledger_account_bookings列 df_ledger = df_financial_mutations[['transaction_id', 'total_amount', 'date', 'ledger_account_bookings']].copy() # 拆分分类账列表为单独行 df_ledger = df_ledger.explode('ledger_account_bookings', ignore_index=True) # 过滤无分类账记录的行 df_ledger = df_ledger.dropna(subset=['ledger_account_bookings']) # 展开字典并添加前缀 df_ledger_normalized = json_normalize(df_ledger['ledger_account_bookings']).add_prefix('ledger_') # 合并基础字段与展开后的分类账字段 df_ledger_final = pd.concat([df_ledger.drop('ledger_account_bookings', axis=1), df_ledger_normalized], axis=1)
- 合并两个结果DataFrame
# 合并后自动对齐列,无对应数据的字段填充NaN df_final = pd.concat([df_payments_final, df_ledger_final], ignore_index=True) # 可选:按交易ID排序,让同交易的记录集中展示 df_final = df_final.sort_values('transaction_id').reset_index(drop=True)
效果说明
- 每条支付记录、分类账记录各自独立成行,不会产生交叉重复的无效数据
- 原交易的基础字段(
transaction_id、total_amount、date)会保留在每一行 - 支付相关字段在分类账行中为NaN,分类账字段在支付行中为NaN,完全匹配需求
内容的提问来源于stack exchange,提问作者Psychotechnopath
相关产品推荐
相关产品推荐

