如何将Pandas中单元格的嵌套字典列表展开为结构化列?
嘿,我来帮你搞定这个Pandas嵌套字典展开的问题!针对你的需求,我整理了一套高效的解决方案,完全适配你提到的300MB量级的DataFrame场景,还能完美处理缺失键的情况。
解决方案:展开Pandas DataFrame中的嵌套字典列表
完整可运行代码
import pandas as pd import numpy as np # 你的示例数据 example = pd.DataFrame([['a', [{'a1': 1, 'a2': {'amount': 20, 'currency': 'USD'}, 'a3': 57}, {'a1': 4, 'a2': {'amount': 50, 'currency': 'USD'}}, {'a1': 7, 'a2': {'amount': 80, 'currency': 'USD'}}], 10, 11], ['b', [{'a1': 13, 'a2': {'amount': 140, 'currency': 'USD'}}, {'a1': 2, 'a2': {'amount': 50, 'currency': 'USD'}}, {'a1': 3, 'a2': {'amount': 90, 'currency': 'USD'}}], 16, 17], ['c', [{'a1': 8, 'a2': {'amount': 75, 'currency': 'USD'}}, {'a1': 9, 'a2': {'amount': 90, 'currency': 'USD'}, 'a3': 98}, {'a1': 6, 'a2': {'amount': 10, 'currency': 'USD'}}], 11, 12]]) example.columns = ['column1', 'column2', 'column3', 'column4'] # 步骤1:将column2的列表拆分为单独行 exploded_df = example.explode('column2', ignore_index=True) # 步骤2:展开嵌套字典(包括a2中的子字典) normalized_df = pd.json_normalize(exploded_df['column2']) # 步骤3:合并原始列与展开后的列 merged_df = exploded_df.drop('column2', axis=1).join(normalized_df) # 步骤4:重命名嵌套列并调整列顺序 merged_df = merged_df.rename(columns={'a2.amount': 'amount', 'a2.currency': 'currency'}) final_df = merged_df[['column1', 'a1', 'amount', 'currency', 'a3', 'column3', 'column4']] # 可选:将NaN替换为None(如果需要Python原生缺失值类型) final_df = final_df.replace(np.nan, None) print(final_df)
代码分步解释
- 步骤1:拆分列表行:用
explode('column2')把每个列表里的字典单独拆成一行,其他列的对应值会自动重复(比如column1的'a'会跟着出现3次,对应3个字典项),ignore_index=True重置索引避免重复混乱。 - 步骤2:展开嵌套字典:
pd.json_normalize是Pandas专门处理嵌套JSON/字典的利器,它能自动识别a2这种嵌套子字典,把里面的amount、currency拆成a2.amount、a2.currency列,还会自动给缺失的键填充NaN——哪怕某个键只在个别行出现,对应的列也会保留,完美适配你的需求。 - 步骤3:合并数据:先删掉原始的
column2列,再用join把展开后的字典DataFrame合并进来,因为两者索引完全对应,合并效率超高。 - 步骤4:调整列名和顺序:把带前缀的嵌套列重命名成你想要的简洁名称,再调整列的顺序和你期望的结果完全对齐。
- 可选替换缺失值类型:Pandas默认用
NaN表示缺失值,如果需要转成Python原生的None,加一行replace(np.nan, None)就行。
性能说明
这个方案用的都是Pandas原生优化过的函数,explode和json_normalize处理大数据量的效率远高于手动循环,对付300MB的DataFrame完全没问题。
内容的提问来源于stack exchange,提问作者ababuji
相关产品推荐
相关产品推荐

