如何检测Pandas DataFrame中两个分类列是否为等价对应关系
Pandas判断两列是否满足等价对应关系的方法
你要验证的规则本质是两列满足双向函数依赖:任意一个列的取值唯一确定另一个列的取值,两列的分组结果完全对齐。以下是两种常用的实现方案:
方法1:基于groupby + nunique 实现(可读性最高)
分别对两列分组,校验每个分组下另一列的唯一值数量是否恒为1,两个校验同时通过即符合要求:
import pandas as pd # 校验函数 def check_equivalent(df, col1, col2): # 校验col1每个值对应唯一的col2 cond1 = df.groupby(col1)[col2].nunique().le(1).all() # 校验col2每个值对应唯一的col1 cond2 = df.groupby(col2)[col1].nunique().le(1).all() return cond1 and cond2 # 符合要求的测试样例 df_valid = pd.DataFrame({ 'col1': ['A','B','B','A','C'], 'col2': ['X','Y','Y','X','Z'] }) print(check_equivalent(df_valid, 'col1', 'col2')) # 输出 True # 不符合要求的测试样例 df_invalid = pd.DataFrame({ 'col1': ['A','B','B','A','C'], 'col2': ['X','X','Y','X','Z'] }) print(check_equivalent(df_invalid, 'col1', 'col2')) # 输出 False
方法2:基于drop_duplicates 实现(性能更高,适合大表)
如果两列满足双向唯一对应,那么两列的去重组合数 = 第一个列的唯一值数 = 第二个列的唯一值数,这个方法避免了两次分组操作,大数据量下运行速度快很多:
def check_equivalent_fast(df, col1, col2): unique_pair_cnt = len(df[[col1, col2]].drop_duplicates()) col1_unique_cnt = df[col1].nunique() col2_unique_cnt = df[col2].nunique() return unique_pair_cnt == col1_unique_cnt == col2_unique_cnt print(check_equivalent_fast(df_valid, 'col1', 'col2')) # 输出 True print(check_equivalent_fast(df_invalid, 'col1', 'col2')) # 输出 False
可选:定位不符合规则的行
如果校验不通过,可以用以下代码快速找出冲突的行:
# 找出col1相同但col2不同的行 conflict_col1 = df_invalid.groupby('col1').filter(lambda x: x['col2'].nunique() > 1) # 找出col2相同但col1不同的行 conflict_col2 = df_invalid.groupby('col2').filter(lambda x: x['col1'].nunique() > 1)
内容的提问来源于stack exchange,提问作者user67275
相关产品推荐
相关产品推荐

