python - 如何删除 pandas Dataframe 中的 "mirror copy"行?

标签 python pandas dataframe subset

我有以下 pandas DataFrame 在 A-B-E 和 C-D-F 之间有“镜像复制”行:

import numpy as np
import pandas as pd

df1 = pd.DataFrame(np.array([[1, 2, 3, 4, 47, 27], [5, 6, 7, 8, 21, 40], [9, 10, 11, 12, 45, 33], 
    [3, 4, 1, 2, 27, 47], [7, 8, 5, 6, 40, 21], [11, 12, 9, 10, 33, 45]]), 
    columns=['A', 'B', 'C', 'D', 'E', 'F'])

print(df1)

##     A   B   C   D   E   F
## 0   1   2   3   4  47  27
## 1   5   6   7   8  21  40
## 2   9  10  11  12  45  33
## 3   3   4   1   2  27  47
## 4   7   8   5   6  40  21
## 5  11  12   9  10  33  45

所谓“镜像副本”,我的意思是:如果您查看第 3、4、5 行,这些是第 0、1、2 行的“镜像副本”。第 0、1、2 行中的 A 列和 B 列是第 3、4、5 行中的 C 列和 D 列。

例如,在第 0 行中,['A', 'B', 'C', 'D'] 为 [1, 2, 3, 4]。在第 3 行中,['A', 'B', 'C', 'D'] 为 [3, 4, 1, 2]。

E 列和 F 列也是如此 --- 第 0、1、2 行中的 E 值是第 3、4、5 行中的 F 值。

我想删除这些“镜像复制”行,只留下“唯一”对。上面的正确输出应该是:

##     A   B   C   D   E   F
## 0   1   2   3   4  47  27
## 1   5   6   7   8  21  40
## 2   9  10  11  12  45  33

##     A   B   C   D   E   F
## 0   3   4   1   2  27  47
## 1   7   8   5   6  40  21
## 2  11  12   9  10  33  45

但不是两者——只有行的一份副本。

我不知道如何对 pandas DataFrame 进行子集化以删除这些行。如何以一种算法有效(不会导致内存爆炸)的方式做到这一点?

我的第一个想法是错误的,因为它只检查每行:

df1 = df1[~((df1.A == df1.C) & (df1.B == df1.D) & (df1.E == df1.F))]

任何帮助表示赞赏!谢谢

最佳答案

您可以执行以下操作:

from collections import Counter

import numpy as np
import pandas as pd


def key(x):
    return frozenset(Counter(x).items())


df = pd.DataFrame(np.array([[1, 2, 3, 4, 47, 27], [5, 6, 7, 8, 21, 40], [9, 10, 11, 12, 45, 33],
                            [3, 4, 1, 2, 27, 47], [7, 8, 5, 6, 40, 21], [11, 12, 9, 10, 33, 45]]),
                  columns=['A', 'B', 'C', 'D', 'E', 'F'])

keys = df[['A', 'B', 'C', 'D', 'E', 'F']].apply(key, axis=1)
mask = keys.duplicated(keep='last')

print(df[mask])

输出

   A   B   C   D   E   F
0  1   2   3   4  47  27
1  5   6   7   8  21  40
2  9  10  11  12  45  33

这个想法是创建一个 keys 列(系列),该列在彼此镜像的那些行上具有相同的值。

这个:

def key(x):
    return frozenset(Counter(x).items())


keys = df[['A', 'B', 'C', 'D', 'E', 'F']].apply(key, axis=1)

创建keys列,然后标记重复的值:

mask = keys.duplicated(keep='last')

您还可以使用@piRSquared建议的 key :

def key(x): 
    a, b, c, d, e, f = x
    return tuple(map(frozenset, [(a, c), (b, d), (e, f)]))

关于python - 如何删除 pandas Dataframe 中的 "mirror copy"行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58512147/

相关文章:

python - 如何根据 id 和 "original date"范围填充 Pandas 数据框?

python - 如何根据对应的值过滤字典键

python - 使用嵌套数组过滤 Pandas DataFrame

python - 使用 if 语句确定 for 循环范围 - pandas.append 在循环中不起作用

python 和 Pandas : display all rows without omitting

根据一列 reshape R 中的数据框

python - Pandas Python : sort dataframe but don't include given row

python - 在wordnet中查找名词的同义词

python - 与 pytest 并行运行单元测试?

python - 根据 Pandas 中的特定条件将值从一列复制到同一行中的其他列