【问题标题】:Get indices from array where element in row satisfies condition从数组中获取行中元素满足条件的索引
【发布时间】:2018-12-08 15:39:02
【问题描述】:

我想找到满足条件的数组的索引。

我有一个 numpy.ndarray B: (m = 行数 = 8 和 3 列)

array([[ 0.,  0.,  0.],
   [ 0.,  0.,  0.],
   [ 0.,  0.,  1.],
   [ 0.,  1.,  1.],
   [ 0.,  1.,  0.],
   [ 1.,  1.,  0.],
   [ 1.,  1.,  1.],
   [ 1.,  0.,  1.],
   [ 1.,  0.,  0.]])

对于每一列,我想找到元素满足以下条件的行的索引: 对于列中的 col: B(row,col)=1 和 B(row+1,col)=1 对于所有 rows=1,2,..,m-1 和 B(row,col)=1 对于 rows=0 和 m。

所以期望的结果是:

Sets1=[[5, 6, 7, 8], [3, 4, 5], [2, 6]]

到目前为止,我已经尝试过:

Sets1=[]
for j in range(3):
    Sets1.append([i for i, x in enumerate(K[1:-1]) if B[x,j]==1 and B[x+1,j]==1])

但这只是条件的第一部分,并给出以下错误输出,因为它采用新集合的索引..所以它实际上应该是加 1..

Sets1= [[4, 5, 6], [2, 3, 4], [1, 5]]

条件的第二部分也适用于索引 0 和 m。还没有。。

编辑:我通过编写 i+1 修复了加 1 部分,并通过添加以下 if 语句尝试了条件的第二部分:

Sets1=[]
for j in range(3):
    Sets1.append([i+1 for i, xp in enumerate(K[1:-1]) if B[xp,j]==1 and B[xp+1,j]==1])
    if B[0,j]==1: Sets1[j].append(0)
    if B[(x-1),j]==1: Sets1[j].append(x-1)

这确实有效,因为它提供了以下输出:

Sets1= [[5, 6, 7, 8], [3, 4, 5], [2, 6]]

所以现在我只需要为条件的第一部分(在 if 语句之前)的列表元素添加 +1...

非常感谢您的帮助!

【问题讨论】:

    标签: python arrays list numpy conditional-statements


    【解决方案1】:

    您可以使用布尔掩码和 np.where

    来完成此操作

    首先,面具:

    c1 = (x==1)
    c2 = (np.roll(x, -1, axis=0) != 0)
    c3 = (x[-1] == 1)
    
    c1 & (c2 | c3)
    
    array([[False, False, False],
           [False, False, False],
           [False, False,  True],
           [False,  True, False],
           [False,  True, False],
           [ True,  True, False],
           [ True, False,  True],
           [ True, False, False],
           [ True, False, False]])
    

    np.where 获取索引:

    >>> np.where(c1 & (c2 | c3))
    
    (array([2, 3, 4, 5, 5, 6, 6, 7, 8], dtype=int64),
     array([2, 1, 1, 0, 1, 0, 2, 0, 0], dtype=int64))
    

    如果您确实希望将结果作为输出中的列表:

    s = np.where(c1 & (c2 | c3))
    [list(s[0][s[1]==i]) for i in range(x.shape[1])]
    
    # [[5, 6, 7, 8], [3, 4, 5], [2, 6]]
    

    【讨论】:

      【解决方案2】:

      numpy 有一种矢量化的方法来做到这一点。首先,我们为 a 等于 1 创建一个掩码:

      mask=a.T==1.0
      

      第二个掩码将判断下一个元素是否也等于 1。由于我们只想要同时满足这两个条件的元素,因此我们将两个掩码相乘:

      mask_next=np.ones_like(mask).astype(bool)
      mask_next[:,:-1]=mask[:,1:]
      fin_mask=mask*mask_next
      

      获取索引:

      idx=np.where(fin_mask)
      

      第一个索引会告诉我们在哪里拆分行 idx:

      split=np.where(np.diff(idx[0]))[0]+1
      out=np.split(idx[1],split)
      

      out 产生预期的结果。如果我理解正确,您希望元素的索引等于 1,而下一个(按列)元素也是 1?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-16
        • 2022-01-08
        • 2021-02-15
        • 1970-01-01
        • 2013-08-14
        • 2018-07-26
        相关资源
        最近更新 更多