基于Group1/Group2分组校验df1的Label序列是否符合df2的ID顺序
DataFrame分组验证Label集合合规性
数据结构
df1
Group1 Group2 Label G1 A1 AA G1 A1 BB G1 A1 CC G1 A2 AA G1 A2 CC G2 A1 BB G2 A1 DD G2 A2 AA G2 A2 CC G2 A2 DD G2 A2 BB
df2
ID Label_ref 1 AA 2 BB 4 CC 5 DD 7 EE
需求
按Group1和Group2分组后,检查每组的Label集合是否符合以下规则:
- 无需包含
df2中所有Label_ref值 - 但不能跳过
df2按ID排序的Label_ref序列中,组内Label覆盖区间里的任何值(即:如果组内包含了序列中第m个和第n个Label_ref,那么第m到第n个之间的所有Label_ref必须都在组内)
预期输出
Group1 Group2 Label Flag G1 A1 AA 1 G1 A1 BB 1 G1 A1 CC 1 G1 A2 AA 0 G1 A2 CC 0 G2 A1 BB 0 G2 A1 DD 0 G2 A2 AA 1 G2 A2 CC 1 G2 A2 DD 1 G2 A2 BB 1
解决方案代码
import pandas as pd # 初始化数据 df1 = pd.DataFrame({ 'Group1': ['G1','G1','G1','G1','G1','G2','G2','G2','G2','G2','G2'], 'Group2': ['A1','A1','A1','A2','A2','A1','A1','A2','A2','A2','A2'], 'Label': ['AA','BB','CC','AA','CC','BB','DD','AA','CC','DD','BB'] }) df2 = pd.DataFrame({ 'ID': [1,2,4,5,7], 'Label_ref': ['AA','BB','CC','DD','EE'] }) # 建立Label到df2中排序位置的映射 label_pos = df2['Label_ref'].reset_index().set_index('Label_ref')['index'] def validate_group(group): # 获取组内所有唯一Label unique_labels = group['Label'].unique() # 获取这些Label在df2中的位置 pos_list = label_pos[label_pos.index.isin(unique_labels)] if len(pos_list) == 0: group['Flag'] = 0 return group # 确定当前组Label覆盖的位置区间 min_pos = pos_list.min() max_pos = pos_list.max() # 获取区间内所有必须存在的Label required_labels = df2.loc[min_pos:max_pos, 'Label_ref'].tolist() # 验证是否所有必须的Label都在组内 if set(required_labels).issubset(unique_labels): group['Flag'] = 1 else: group['Flag'] = 0 return group # 分组应用验证逻辑 result = df1.groupby(['Group1', 'Group2'], group_keys=False).apply(validate_group) print(result)
代码说明
- 建立位置映射:先将
df2的Label_ref按ID排序后的位置记录下来,方便快速查找每个Label对应的顺序位置。 - 分组验证:
- 对每个分组提取唯一Label集合
- 找到这些Label在
df2中的最小和最大位置,确定需要覆盖的区间 - 检查区间内的所有Label是否都在组内,是则标记Flag为1,否则为0
- 合并结果:将验证结果合并回原DataFrame,得到最终带Flag的输出。
内容的提问来源于stack exchange,提问作者z star
相关产品推荐
相关产品推荐

