【问题标题】:How to perform contain operation between a numpy array and a vector row-wise?如何在 numpy 数组和向量行之间执行包含操作?
【发布时间】:2018-07-10 13:00:56
【问题描述】:

现在我有一个 numpy 数组,

[[1 2]
 [3 4]
 [2 5]]

还有一个向量。

[2,
 5,
 2]

我想在数组和向量行之间执行包含操作。也就是说,我要检查第一行[1, 2]是否包含2,第二行[3, 4]是否包含5。预期的输出如下所示:

[True, False, True] 

我该如何实现这个功能?非常感谢。

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    您可以将向量广播到一列中,将其等同于矩阵行中的所有元素,并查看每行中any元素是否为True

    import numpy as np
    
    a = np.array(
        [[1, 2],
         [3, 4],
         [2, 5]])
    v = np.array([2, 5, 2]).reshape(-1, 1)
    
    np.any(a == v, axis=1)
    

    https://ideone.com/YmWtlv

    reshape 将您的一维(行)向量转换为列向量。这是必要的,因为通常broadcasting 沿右侧排列形状,因此您需要明确的尾随维度 1。完成相同操作的另一种方法是使用 newaxis(又名None):

    v = np.array([2, 5, 2])[..., np.newaxis]
    

    注意

    我最初的答案建议reduce 使用logical_or,这只是any 的一种更复杂的说法:

    np.logical_or.reduce(a == v, axis=1)
    

    【讨论】:

      【解决方案2】:

      使用列表理解和压缩

      arr = np.array([[1, 2],[3, 4],[2, 5]])
      a = np.array([2,5,2])
      
      [y in x for x, y in zip(arr, a)]
      # outputs: [True, False, True]
      

      将 np.any 与 axis=1 一起使用:

      np.any(arr == a[:, None], axis=1)
      # outputs: array([ True, False,  True])
      

      【讨论】:

      • 这里的任何解决方案都是最好的。不知道第一部分的意义是什么。
      • 列表理解只是我想到的第一个。
      【解决方案3】:

      这个单行应该做到这一点。它也适用于任意数量的列。

      # Set up
      import numpy as np
      array = np.array([[1, 2],[3, 4],[2, 5]])
      vector = np.array([2,5,2])
      
      # Solution
      result = np.logical_or.reduce(array == vector[:,None], 1)
      

      输出:

      [ True, False,  True]
      

      这会将所有元素与 column 向量 vector 进行比较,然后减少行数。

      【讨论】:

      • 是的,numpy 就是关于速度的。但是你能解释一下我什么时候可以在ufunc之后使用reduce吗?谢谢。
      • 您唯一缺少的就是广播。无需创建一个完整的额外矩阵并乘以它。
      【解决方案4】:

      我们也可以利用广播和点积。

      a = np.array([[1, 2], [3, 4], [2, 5]])
      b = np.array([2, 5, 2]) 
      

      解决方案

      (a == b[:,None]) @ np.array([1, 1]).astype(bool) 
      

      【讨论】:

      • @MadPhysicist 谢谢。你的也很聪明。
      【解决方案5】:

      可以将二维数组的第一列和第二列与向量进行比较,对得到的结果进行logical or操作。

      import numpy as np
      a = np.array([[1, 2],[3, 4],[2, 5]])
      b = [2,5,2]
      np.logical_or(a[:,0] == b , a[:,1] == b)
      

      输出:

      array([ True, False,  True], dtype=bool)
      

      【讨论】:

      • @QYang - 我在答案中给出的解决方案比这个快大约 3 倍,因为它不需要解压缩 a 的列。
      • 这不是一个非常通用的解决方案。
      • @MadPhysicist,我同意。看起来其他答案(包括您的答案)有更好的解决方案。否决票不是太苛刻了吗?
      • 很公平。毕竟我想你的解决方案是有效的。
      猜你喜欢
      • 1970-01-01
      • 2014-03-11
      • 1970-01-01
      • 2019-09-11
      • 1970-01-01
      • 2022-11-10
      • 2020-05-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多