【问题标题】:How to filter duplicates with swapping column names in pandas如何在熊猫中通过交换列名过滤重复项
【发布时间】:2020-12-10 19:10:50
【问题描述】:

我有一个如下所示的 pd.Dataframe:

   a_p1  a_x1  a_x2  b_p1  b_x1  b_x2
1   0.0   0.0   0.0   1.0  -1.0   0.0
2   1.0  -1.0   0.0   0.0   0.0   0.0
3   0.0   0.0   0.0   0.0  -1.0   0.0
4   0.0   0.0   1.0   0.0   0.0   1.0
5   0.0   1.0   0.0   0.0   0.0   1.0
6   0.1   0.0   0.0   0.2   0.0   1.0
7   0.1   0.0   1.0   0.2   0.0   0.0
...

a_ 和 b_ 代表赌博。它们的顺序不是必需的,所以 a_ 也可以是 b_。 我想删除第 1 行和第 2 行中的重复项:第 1 行中的赌博对与第 2 行中的相同,只是赌博 a 和 b 交换了位置。

如何过滤我的数据框以便只保留其中一行?

期望的输出:

   a_p1  a_x1  a_x2  b_p1  b_x1  b_x2
1   0.0   0.0   0.0   1.0  -1.0   0.0
2   0.0   0.0   0.0   0.0  -1.0   0.0
3   0.0   0.0   1.0   0.0   0.0   1.0
4   0.0   1.0   0.0   0.0   0.0   1.0
5   0.1   0.0   0.0   0.2   0.0   1.0
6   0.1   0.0   1.0   0.2   0.0   0.0
...

【问题讨论】:

  • a_p1 可以是b_x1 吗?和a_p1a_x1?
  • 没有。当且仅当'a_x1'是'b_x1'并且'a_x2'是'b_x2'时'a_p1'可以是'b_p1'。基本上,有两个块:以 a_ 开头的列和以 b_ 开头的列。这些是可以互换的,但是在一个区块内是不可能互换的。

标签: python pandas dataframe filter


【解决方案1】:

如果所有列名都被排序 - 在_之后按列值分组,将值转换为元组,排序并使用duplicated作为掩码:

df1 = df.rename(columns=lambda x: x.split('_')[0])
print (df1)
     a    a    a    b    b    b
1  0.0  0.0  0.0  1.0 -1.0  0.0
2  1.0 -1.0  0.0  0.0  0.0  0.0
3  0.0  0.0  0.0  0.0 -1.0  0.0
4  0.0  0.0  1.0  0.0  0.0  1.0
5  0.0  1.0  0.0  0.0  0.0  1.0
6  0.1  0.0  0.0  0.2  0.0  1.0
7  0.1  0.0  1.0  0.2  0.0  0.0

print (df1.groupby(df1.columns, axis=1)
          .apply(lambda x: x.apply(lambda x: tuple(x), 1))
          .apply(lambda x: tuple(sorted(x)), axis=1))
1    ((0.0, 0.0, 0.0), (1.0, -1.0, 0.0))
2    ((0.0, 0.0, 0.0), (1.0, -1.0, 0.0))
3    ((0.0, -1.0, 0.0), (0.0, 0.0, 0.0))
4     ((0.0, 0.0, 1.0), (0.0, 0.0, 1.0))
5     ((0.0, 0.0, 1.0), (0.0, 1.0, 0.0))
6     ((0.1, 0.0, 0.0), (0.2, 0.0, 1.0))
7     ((0.1, 0.0, 1.0), (0.2, 0.0, 0.0))
dtype: object

m = (df1.groupby(df1.columns, axis=1)
         .apply(lambda x: x.apply(lambda x: tuple(x), 1))
         .apply(lambda x: tuple(sorted(x)), axis=1)
         .duplicated())

df2 = df[~m]
print (df2)
   a_p1  a_x1  a_x2  b_p1  b_x1  b_x2
1   0.0   0.0   0.0   1.0  -1.0   0.0
3   0.0   0.0   0.0   0.0  -1.0   0.0
4   0.0   0.0   1.0   0.0   0.0   1.0
5   0.0   1.0   0.0   0.0   0.0   1.0
6   0.1   0.0   0.0   0.2   0.0   1.0
7   0.1   0.0   1.0   0.2   0.0   0.0

【讨论】:

  • 这不会也将这些行视为重复:0.1 0 0 0.2 0 1, 0.1 0 1 0.2 0 0?
  • 假设我有评论中描述的列。我认为您的代码会将它们错误地视为重复项。没有?
  • @MaxJ。 - 答案已编辑为原始答案,也没有仅删除第二行,最后一行没有。
猜你喜欢
  • 1970-01-01
  • 2019-04-04
  • 1970-01-01
  • 1970-01-01
  • 2018-11-08
  • 1970-01-01
  • 2019-05-21
  • 2021-11-02
  • 1970-01-01
相关资源
最近更新 更多