在Pandas中为DataFrame添加对应ID项的去重有序汇总新列
解决方案:Pandas列表列的汇总、去重与排序
先看原始数据:
import pandas as pd df1 = pd.DataFrame({"ID":[1, 2, 3, 4], "item":[[22, 78], [78], [78,79], [78,456,254]]}) df2 = pd.DataFrame({"IDs":[[1,2], [3], [1,3,4], [3,4]]})
需求是给df2添加all_items列,规则为:
- 汇总
IDs列表中每个ID对应的df1里的item元素 - 去除重复元素
- 按元素出现次数降序排列
实现步骤:
1. 预处理df1,统计item元素的出现频次
先把df1的item列展开为单行元素,方便统计频次:
# 展开item列表,每个元素单独占一行 exploded_df1 = df1.explode('item') # 统计每个item的出现次数,转成字典方便后续调用 item_counts = exploded_df1['item'].value_counts().to_dict()
2. 建立ID到item列表的映射
用df1的ID作为索引,快速获取对应ID的item列表:
id_to_items = df1.set_index('ID')['item'].to_dict()
3. 定义处理函数,生成符合要求的all_items列表
写一个函数,输入IDs列表,输出去重并按频次排序的元素列表:
def get_all_items(ids_list): # 汇总所有ID对应的item元素 all_elements = [] for idx in ids_list: all_elements.extend(id_to_items[idx]) # 去重,同时保留元素第一次出现的顺序 unique_elements = list(dict.fromkeys(all_elements)) # 按出现频次降序排序,频次相同则按首次出现顺序排列 unique_elements.sort(key=lambda x: (-item_counts[x], all_elements.index(x))) return unique_elements
4. 应用函数到df2,生成新列
df2['all_items'] = df2['IDs'].apply(get_all_items)
最终结果
运行后df2的输出与期望一致:
print(df2) # 输出: # IDs all_items # 0 [1, 2] [78, 22] # 1 [3] [78] # 2 [1, 3, 4] [78, 22, 79, 456, 254] # 3 [3, 4] [78, 79, 456, 254]
补充说明
explode是Pandas处理列表列的常用技巧,能快速将列表元素拆分为单行,方便统计dict.fromkeys(all_elements)实现去重的同时保留元素首次出现的顺序- 排序时用
-item_counts[x]实现频次降序,all_elements.index(x)保证频次相同时按原顺序排列
内容的提问来源于stack exchange,提问作者Mr.Slow
相关产品推荐
相关产品推荐

