如何展开Pandas DataFrame列中的嵌套键值对并去重生成新列?
Pandas处理嵌套字典列并去重的解决方案
问题背景
给定字典列表转换为DataFrame后,需要将RelatedPosts列中的嵌套字典的Type、Section键展开为新列,且每行新列的值需去重(如Scott的Type列仅保留一个'daily',James保留'daily'和'weekly'),同时需适配5-10万行的大数据量。
方法一:自定义函数+Apply(适合新手理解)
逻辑直观,快速上手:
import pandas as pd # 原始数据 list_payloads = [ { 'Id': 320409, 'Name': 'James', 'RelatedPosts':[{'Type':'daily', 'Section':'news'},{'Type':'daily', 'Section':'sports'},{'Type':'weekly', 'Section':'shows'}] }, { 'Id': 334051, 'Name': 'Scott', 'RelatedPosts':[{'Type':'daily', 'Section':'news'},{'Type':'daily', 'Section':'sports'}] } ] # 1. 转换为DataFrame df = pd.DataFrame(list_payloads) # 2. 定义函数提取去重的Type和Section def get_unique_items(row): # 用集合去重,再转回列表 unique_types = list({item['Type'] for item in row['RelatedPosts']}) unique_sections = list({item['Section'] for item in row['RelatedPosts']}) return pd.Series([unique_types, unique_sections], index=['Type', 'Section']) # 3. 应用函数生成新列 df[['Type', 'Section']] = df.apply(get_unique_items, axis=1) # 4. 移除原嵌套列(可选) df.drop('RelatedPosts', axis=1, inplace=True) print(df)
输出结果:
Id Name Type Section 0 320409 James [daily, weekly] [news, sports, shows] 1 334051 Scott [daily] [news, sports]
方法二:Explode+GroupBy(更高效,适合大数据量)
针对5-10万行数据集,利用Pandas矢量化操作提升效率:
import pandas as pd # 原始数据同上,省略重复代码 df = pd.DataFrame(list_payloads) # 1. 将RelatedPosts的列表拆分为多行 exploded_df = df.explode('RelatedPosts') # 2. 拆分嵌套字典为独立列 exploded_df = pd.concat( [exploded_df.drop('RelatedPosts', axis=1), exploded_df['RelatedPosts'].apply(pd.Series)], axis=1 ) # 3. 按Id和Name分组,聚合去重后的Type和Section result_df = exploded_df.groupby(['Id', 'Name']).agg( Type=('Type', lambda x: list(set(x))), Section=('Section', lambda x: list(set(x))) ).reset_index() print(result_df)
输出结果与方法一完全一致,大数据量场景下处理速度更优。
为什么json_normalize没得到预期结果?
pd.json_normalize()会将每个嵌套字典拆分为独立行,导致原数据的每行被拆分为多行(比如James会变成3行),而非保留原行并聚合去重后的值,因此不符合需求。
内容的提问来源于stack exchange,提问作者Matt Ezq
相关产品推荐
相关产品推荐

