如何在多次Pandas分组操作中建立映射以跟踪原始ID的分组归属
如何在多次Pandas分组操作中建立映射以跟踪原始ID的分组归属
我完全懂你的需求——每次做分组聚合后,总担心丢失原始id的分组归属信息,比如哪些原始id属于同一个a组,后续再按b分组后,这些id又归到哪个b组里对吧?别着急,咱们一步步来实现这个追踪功能:
首先先把你的原始数据代码放出来,方便大家复现:
import numpy as np import pandas as pd np.random.seed(1) df = pd.DataFrame({ 'id': np.arange(10), 'a': np.random.randint(1, 10, 10), 'b': np.random.randint(1, 10, 10), 'c': np.random.randint(1, 10, 10) })
第一步:记录第一次分组(按a)的原始ID归属
在执行聚合前,我们先建立两个关键映射:
- 单个
id到对应a值的映射,方便快速查某个id属于哪个a组 - 每个
a值对应的所有原始id列表,保留组内的所有成员
代码实现如下:
# 建立id到a的一对一映射 id_to_a = df.set_index('id')['a'].to_dict() # 建立a到对应所有id的一对多映射 a_group_ids = df.groupby('a')['id'].apply(list).to_dict() # 然后再执行你原本的第一次聚合操作 new_df = df.groupby('a').agg('max').reset_index()
现在a_group_ids里就存着你要的信息:比如a=3对应的原始id是[3,6,8],完全符合你的要求。
第二步:关联第一次分组和第二次分组(按b)的归属
接下来我们给第一次聚合后的new_df加上原始id列表的列,这样在第二次分组时就能把这些id带进去:
# 给new_df添加原始id列,把每个a对应的id列表关联上 new_df['original_ids'] = new_df['a'].map(a_group_ids) # 执行第二次分组聚合,注意要把original_ids列合并起来 second_new_df = new_df.groupby('b').agg({ 'a': 'max', 'id': 'max', 'c': 'max', 'original_ids': lambda x: [item for sublist in x for item in sublist] # 合并同一b组下的所有原始id }).reset_index()
现在看second_new_df,每个b分组对应的original_ids列就会列出所有属于这个b组的原始id,比如b=2对应的是[2],b=7对应的是[5,7],完美追踪到了归属关系。
进阶:直接获取原始ID到最终分组的映射
如果需要更直接的结果,比如每个原始id最终属于哪个b分组,我们可以生成一个一对一的映射字典:
id_to_final_b = {} for _, row in second_new_df.iterrows(): for original_id in row['original_ids']: id_to_final_b[original_id] = row['b'] # 举个例子,查id=3的最终分组 print(id_to_final_b[3]) # 输出8,和原始数据里的b值一致
核心思路总结
其实关键就是不要只做聚合,在每一步分组前先把分组键和原始id的关联关系保存下来,这样不管做多少次分组操作,都能通过映射链一步步追踪到每个原始id的归属,再也不用担心聚合后丢失关键信息啦!
备注:内容来源于stack exchange,提问作者Eran Moshe
相关产品推荐
相关产品推荐

