检查熊猫中的多值重复

时间:2021-06-01 09:08:07

标签: python pandas dataframe

输入

我有一个包含多列的数据框。

proof_path = 

   #1  X  Y  #2 X_  Z  #3  W Z_  #4 W_ Y_
0  p1  a  b  p2  a  c  p2  a  c  p3  a  b
1  p1  a  b  p2  a  c  p3  a  c  p1  a  b
2  p1  a  b  p2  a  d  p3  e  d  p4  e  b

在上面的 Dataframe 中,我想检查每一行是否在 [#1, X, Y][#2, X_, Z][#3, W, Z_][#4, W_, Y_] 之间重复。

例如,在索引 0 对应的行中,[#2, X_, Z][#3, W_, Z_][P2, a, c] 重叠。 另外,索引1对应的行中的[#1, X, Y][#4, W_, Y_]重叠[P1, a, b]。我将删除该数据框中这些多值之间重叠的行。

我想要的输出是

输出

proof_path = 

   #1  X  Y  #2 X_  Z  #3  W Z_  #4 W_ Y_
2  p1  a  b  p2  a  d  p3  e  d  p4  e  b

我尝试如下。

triple_size = 3
for depth in range(int(len(proof_path.columns)/triple_size)-1):
    for i in range(1, int(len(proof_path.columns)/triple_size)-depth):
        current_rComp = proof_path.iloc[:, depth*size:(depth+1)*triple_size]
        next_rComp = proof_path.iloc[:, (depth+i)*size:(depth+i+1)*triple_size]
        current_rComp.columns = ['pred', 'subj', 'obj']
        next_rComp.columns = ['pred', 'subj', 'obj']
        proof_path = proof_path[current_rComp.ne(next_rComp).any(axis=1)]

虽然这些方法能够达到预期的结果,但它们通过为每次迭代生成 proof_path 的子集而效率低下。有没有简单的方法来完成这些任务?

1 个答案:

答案 0 :(得分:1)

为了避免嵌套循环,您可以使用集合:对于每一行,将四个三元组的值放在一个集合中。集合中元素的数量是唯一三元组的数量。然后你可以使用这个数量的唯一三元组作为掩码来选择行:

import numpy as np

proof_path['n_unique_triples'] = \
    proof_path.apply(lambda row: len(set((tuple(row[0:3]),
                                          tuple(row[3:6]),
                                          tuple(row[6:9]),
                                          tuple(row[9:12])))), axis=1)
    
df_select = proof_path[proof_path.n_unique_triples == 4]
df_select
    #1  X   Y   #2  X_  Z   #3  W   Z_  #4  W_  Y_  n_unique_triples
2   p1  a   b   p2  a   d   p3  e   d   p4  e   b   4