如何比较Dataframe中的多值重复项

2024-10-06 12:37:00 发布

您现在位置:Python中文网/ 问答频道 /正文

输入

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

proof_path = 

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

rule = [('#1', 'X', 'Y'), ('#2', 'X', 'Z'), ('#3', 'W', 'Z'), ('#4', 'W', 'Y')]

在上面的数据框中,我想检查每一行是否在(#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  Z  #3  W  #4
2  p1  a  b  p2  d  p3  e  p4

我尝试了以下方法

for depth in range(len(rule)-1):
    for i in range(1, len(rule)-depth):
        current_rComp = proof_path[[rule[depth][0], rule[depth][1], rule[depth][2]]]
        current_rComp.columns = ['pred', 'subj', 'obj']
        next_rComp = proof_path[[rule[i+depth][0], rule[i+depth][1], rule[i+depth][2]]]
        next_rComp.columns = ['pred', 'subj', 'obj']
        proof_path = proof_path[current_rComp.ne(next_rComp).any(axis=1)]

尽管这些方法能够达到预期的结果,但它们通过为每次迭代生成新的数据帧而效率低下。有没有简单的方法来完成这些任务


Tags: 数据path方法inforcurrentrulenext
2条回答

创建一个占位符mask,最初包含False个值,如果在相应的行中发现任何重复项,则该mask将包含True

rule列表中生成长度为2combinations,然后对每个组合比较数据帧的切片以创建布尔掩码,现在使用all沿axis=1减少此掩码,并使用占位符掩码获取减少的掩码的逻辑or

from itertools import combinations

mask = np.full(len(df), False)
for x, y in combinations(rule, 2):
    mask |= (df[[*x]].values == df[[*y]].values).all(1)

或者,我们也可以将上述方法封装在列表中

mask = np.any([(df[[*x]].values == df[[*y]].values).all(1) 
               for x, y in combinations(rule, 2)], axis=0)

>>> df[~mask]

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

您可以删除列子集上具有重复项的行,如-

df = df.drop_duplicates(subset=['#1', 'X', 'Y'],keep=False)
df = df.drop_duplicates(subset=['#2', 'X', 'Z'],keep=False)
df = df.drop_duplicates(subset=['#3', 'W', 'Z'],keep=False)

有关其他参数,请参阅documentation

相关问题 更多 >