如何在Pandas DataFrame中标记两列值是否存在反向互换情况
嘿,作为Pandas新手碰到这个需求完全没问题,我给你捋个简单易懂的实现思路,附带代码示例~
核心思路
要判断某一行的(a,b)是否存在反向的(b,a)行,本质上就是看这两个值组成的无序对在整个DataFrame里出现过不止一次。所以我们可以把每一行的a和b转换成「有序对」(比如把小的放前面,大的放后面),这样反向的行就会变成完全一样的有序对,接下来只要统计每个有序对的出现次数,次数大于1就说明存在反向行啦!
具体代码实现
先整个示例DataFrame方便你测试:
import pandas as pd # 示例数据,包含一组反向行(1,2)和(2,1) df = pd.DataFrame({ 'a': [1, 2, 3, 4, 2], 'b': [2, 1, 5, 6, 3] })
然后一步步处理:
- 生成每行的有序对:
# 把每行的a和b排序后转成元组,这样反向的行会得到相同的元组 df['pair'] = df.apply(lambda x: tuple(sorted([x['a'], x['b']])), axis=1)
- 统计每个有序对的出现次数,并用这个次数生成c列:
这里给你两种写法,第二种更高效,适合大数据量:
写法1(直观易懂)
# 统计每个pair的出现次数 pair_counts = df['pair'].value_counts() # 把次数映射回原DataFrame,再判断是否大于1 df['c'] = df['pair'].map(pair_counts).apply(lambda x: 1 if x > 1 else 0)
写法2(高效简洁)
# 用groupby+transform直接计算每个组的数量,再转成0/1 df['c'] = df.groupby('pair')['pair'].transform('count').gt(1).astype(int)
- 最后可以删掉中间的
pair列(如果不需要的话):
df = df.drop('pair', axis=1)
预期输出
运行后你会得到这样的结果:
a b c 0 1 2 1 1 2 1 1 2 3 5 0 3 4 6 0 4 2 3 0
可以看到前两行因为是反向对,c列标记为1,其他行没有对应的反向行,标记为0,完全符合你的需求~
另外补充一句:不管你的a、b列是数字还是字符串,这个方法都能用,因为sorted()对字符串也能正常排序哦!
内容的提问来源于stack exchange,提问作者max
相关产品推荐
相关产品推荐

