【问题标题】:Filter rows in numpy array based on second array根据第二个数组过滤numpy数组中的行
【发布时间】:2022-01-20 16:21:41
【问题描述】:

我有 2 个二维 numpy 数组 A 和 B 我想删除 A 中出现在 B 中的所有行。

我尝试过这样的事情:

A[~np.isin(A, B)]

但是 isin 保留了 A 的维度,我需要每行一个布尔值来过滤它。

编辑:像这样

A = np.array([[3, 0, 4],
              [3, 1, 1],
              [0, 5, 9]])
B = np.array([[1, 1, 1],
              [3, 1, 1]])

.....

A = np.array([[3, 0, 4],
              [0, 5, 9]])

【问题讨论】:

  • 我认为一个简短的例子会更好地说明你的问题
  • 您的阵列实际有多大?这些项目是否有一个很小的价值?它们总是正整数吗?

标签: python numpy


【解决方案1】:

可能不是最高效的解决方案,但正是您想要的。您可以将AB 的dtype 更改为由一行组成的单元。您需要首先确保数组是连续的,例如ascontiguousarray:

Av = np.ascontiguousarray(A).view(np.dtype([('', A.dtype, A.shape[1])])).ravel()
Bv = np.ascontiguousarray(B).view(Av.dtype).ravel()

现在你可以直接申请np.isin了:

>>> np.isin(Av, Bv)
array([False,  True, False])

根据文档,invert=True 比否定isin 的输出要快,所以你可以这样做

A[np.isin(Av, Bv, invert=True)]

【讨论】:

  • 这很聪明,但是:A = np.array([[3, 0, 4], [3, 1, 1], [0, 5, 9]], order="F")(在你说“哦,这只是一个奇怪的角落条件”之前,这是 .transpose() 返回的顺序)
  • @CJR。我很清楚order='F' 的来源。显然,这仅在最后一个轴是连续的情况下才有效。能够使用 Fortran 有序数组创建视图实际上已被弃用,您应该会看到警告。我为下一个版本删除了它:github.com/numpy/numpy/pull/20722
  • 如何使用副本来确保排序/连续性正确?
  • @JérômeRichard。已添加
  • @CJR。修复了复制问题
【解决方案2】:

尝试以下方法 - 它使用矩阵乘法来降低维度:

import numpy as np

A = np.array([[3, 0, 4],
              [3, 1, 1],
              [0, 5, 9]])
B = np.array([[1, 1, 1],
              [3, 1, 1]])

arr_max = np.maximum(A.max(0) + 1, B.max(0) + 1)
print (A[~np.isin(A.dot(arr_max), B.dot(arr_max))])

输出:

[[3 0 4]
 [0 5 9]]

【讨论】:

  • 哦,哇,是的,这就是我想要的,从 A 中删除 B 中存在的行。但我不知道它是如何工作的:D
  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
  • 这很聪明,但是:A = np.array([[1, 0, 0], [1, 1, 0], [0, 1, 1]])B = np.array([[1, 1, 0], [1, 0, 1]])
  • 聪明。不完美,但一个好主意
  • 答案可能是 not 总是有效,因为点积不会生成 unique 值。我认为缺少累积的产品(例如当我们展平 ND 阵列时)。另外,如果最大值很大或者数组的大小很大,那么肯定会有一些溢出导致bug。
【解决方案3】:

这当然不是最高效的解决方案,但它相对容易阅读:

A = np.array([row for row in A if row not in B])

编辑:

我发现代码无法正常工作,但确实如此:

A = [row for row in A if not any(np.equal(B, row).all(1))]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-29
    • 2022-11-04
    • 2022-11-20
    • 1970-01-01
    • 2021-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多