【问题标题】:Select all rows from Numpy array where each column satisfies some condition从 Numpy 数组中选择每列满足某些条件的所有行
【发布时间】:2021-08-08 07:33:42
【问题描述】:

我有一个数组x

x = [[1,2,3,...,7,8,9],
[1,2,3,...,7,9,8],
...,
[9,8,7,...,3,1,2],
[9,8,7,...,3,2,1]]

我还为每一列设置了一个不允许的数字数组。我想选择每列中只允许字符的所有行。例如,我可能只想要第一列中没有任何[1,2,3] 的行;我可以这样做,

x[~np.in1d(x[:,0], [1,2,3])]

对于任何单个列,我都可以做到这一点。但我希望基本上一次对 all 列执行此操作,只选择每个元素是其列的允许编号的行。我似乎无法让 x.anyx.all 做好这件事 - 我该怎么做?

编辑:为了澄清,每列的不允许数字是不同的。实际上,我会有一些数组 y,

y = [[1,4,...,7,8],
[2,5,...,9,4],
[3,6,...,8,6]]

我想要来自 x 的行,其中第 1 列不能在 [1,2,3] 中,第 2 列不能在 [4,5,6] 中,依此类推。

【问题讨论】:

    标签: python numpy numpy-ndarray numpy-slicing


    【解决方案1】:

    您可以broadcast比较,然后all查看:

    x[(x != y[:,None,:]).all(axis=(0,-1))]
    

    分解:

    # compare each element of `x` to each element of `y`
    # mask.shape == (y.shape[0], x.shape[0], x.shape[1])
    mask = (x != y[:,None,:])
    
    # `all(0)` checks, for each element in `x`, it doesn't match any element in the same column of `y`
    # `all(-1) checks along the rows of `x`
    mask = mask.all(axis=(0,-1)
    
    # slice
    x[mask]
    

    例如,考虑:

    x = np. array([[1, 2],
           [9, 8],
           [5, 6],
           [7, 8]])
    
    y = np.array([[1, 4],
           [2, 5],
           [3, 7]])
    

    然后mask = (x != y[:,None,:]).all(axis=(0,1))给了

    array([False,  True,  True,  True])
    

    【讨论】:

    • 你能再解释一下吗?这里的 y 是什么,这条线到底在做什么?
    • 嗯,我不确定如何实现它以供我使用。我应该更明确一点 - 不允许的数字 对于每一列都不同 - 我可能不想在第 1 列中出现 [1,2,3],但又不想在 [4,5,8] 中出现第 2 列。这仍然适用吗?
    【解决方案2】:

    现在建议使用np.isin 而不是np.in1d。这可以让您 (a) 一次比较整个数组,并且 (b) 更有效地反转掩码。

    x[np.isin(x, [1, 2, 3], invert=True).all(1)]
    

    np.isin 保留x 的形状,因此您可以在列中使用.all。它还有一个invert 参数,可以让您执行与~isin(x, [1, 2, 3]) 等效的操作,但效率更高。

    此解决方案将类似的计算向量化为另一个更有效的建议(尽管它仍然是线性搜索),并且还避免创建临时数组。

    【讨论】:

      猜你喜欢
      • 2014-07-17
      • 1970-01-01
      • 1970-01-01
      • 2013-04-13
      • 2019-12-04
      • 1970-01-01
      • 1970-01-01
      • 2020-12-06
      • 2021-11-04
      相关资源
      最近更新 更多