仅允许Pandas DataFrame中两列之间的一对一映射
我有一个包含两列的数据表 df,每一行都是独特的。在一列中的一个元素可以对应到另一列中的一个或多个元素。我想要把那些元素过滤掉。最终的数据表中,一列中的一个元素只能对应到另一列中的一个独特元素。
我现在的做法是先按一列分组,然后统计重复的数量,再把数量超过1的行去掉。然后对另一列再做一次。我在想有没有更好、更简单的方法。
谢谢
补充1:我刚意识到我的解决方案是错误的,去掉A列中多重映射的元素会减少B列中的映射数量,看看下面这个例子:
A B
1 4
1 3
2 4
1对应3和4,所以前两行应该被去掉,而4又对应1和2。最终的表格应该是空的。然而,我的解决方案会保留最后一行。
有没有人能给我一个快速简单的解决方案?谢谢
1 个回答
2
好吧,你可以这样做:
>>> df
A B
0 1 4
1 1 3
2 2 4
3 3 5
你只想保留一行数据,前提是没有其他行的'A'列有值为'A',而且没有其他行的'B'列有值为'B'。在这个例子中,只有第三行符合这些条件:
>>> Aone = df.groupby('A').filter(lambda x: len(x) == 1)
>>> Bone = df.groupby('B').filter(lambda x: len(x) == 1)
>>> Aone.merge(Bone,on=['A','B'],how='inner')
A B
0 3 5
解释:
>>> Aone = df.groupby('A').filter(lambda x: len(x) == 1)
>>> Aone
A B
2 2 4
3 3 5
上面的代码是根据'A'列的值来筛选可能允许的行。
>>> Bone = df.groupby('B').filter(lambda x: len(x) == 1)
>>> Bone
A B
1 1 3
3 3 5
上面的代码是根据'B'列的值来筛选可能允许的行。然后把这两部分的交集合并在一起,就得到了同时满足两个条件的行:
>>> Aone.merge(Bone,on=['A','B'],how='inner')
注意,你也可以用 groupby/transform
做类似的事情。不过,transform的速度比较慢,所以我没有把它作为替代方案。