【问题标题】:Assigning to slices of 2D NumPy array分配给二维 NumPy 数组的切片
【发布时间】:2018-07-30 06:40:34
【问题描述】:

我想将0 分配给二维数组的不同长度切片。

例子:

import numpy as np    

arr = np.array([[1,2,3,4],
                [1,2,3,4],
                [1,2,3,4],
                [1,2,3,4]])

idxs = np.array([0,1,2,0])

鉴于上述数组arr 和索引idxs,您如何分配给不同长度的切片。这样的结果是:

arr = np.array([[0,2,3,4],
                [0,0,3,4],
                [0,0,0,4],
                [0,2,3,4]])

这些不起作用

slices = np.array([np.arange(i) for i in idxs])
arr[slices] = 0

arr[:, :idxs] = 0

【问题讨论】:

    标签: python arrays numpy indexing slice


    【解决方案1】:

    这是一个稀疏解决方案,在只有一小部分位置应该归零的情况下可能很有用:

    >>> idx = idxs+1
    >>> I = idx.cumsum()
    >>> cidx = np.ones((I[-1],), int)
    >>> cidx[0] = 0
    >>> cidx[I[:-1]]-=idx[:-1]
    >>> cidx=np.cumsum(cidx)
    >>> ridx = np.repeat(np.arange(idx.size), idx)
    >>> arr[ridx, cidx]=0
    >>> arr
    array([[0, 2, 3, 4],
           [0, 0, 3, 4],
           [0, 0, 0, 4],
           [0, 2, 3, 4]])
    

    解释:我们需要构造我们想要放零的位置的坐标。

    行索引很简单:我们只需要从 0 到 3 重复每个数字来填充相应的切片。

    列索引从 0 开始,并且大部分时间递增 1。因此,为了构造它们,我们在大多数情况下使用 cumsum。仅在每个新行的开头我们必须重置。我们通过减去相应切片的长度来做到这一点,例如取消我们在该行中求和的那些。

    【讨论】:

    • @JamesSchinner 我已经添加了一些解释。
    • 非常感谢。这似乎确实是大型数组的必经之路。
    【解决方案2】:
    import numpy as np
    
    arr = np.array([[1, 2, 3, 4],
                    [1, 2, 3, 4],
                    [1, 2, 3, 4],
                    [1, 2, 3, 4]])
    
    idxs = np.array([0, 1, 2, 0])
    
    for i, idx in enumerate(idxs):
        arr[i,:idx+1] = 0
    

    【讨论】:

      【解决方案3】:

      这就是诀窍:

      import numpy as np    
      
      arr = np.array([[1,2,3,4],
                     [1,2,3,4],
                     [1,2,3,4],
                     [1,2,3,4]])
      idxs = [0,1,2,0]
      for i,j in zip(range(arr.shape[0]),idxs):
        arr[i,:j+1]=0
      

      【讨论】:

        【解决方案4】:

        您可以使用广播比较来生成掩码,并相应地索引到arr

        arr[np.arange(arr.shape[1]) <= idxs[:, None]] = 0
        

        print(arr) 
        array([[0, 2, 3, 4],
               [0, 0, 3, 4],
               [0, 0, 0, 4],
               [0, 2, 3, 4]])
        

        【讨论】:

        • 太棒了!一旦我看到解决方案,它看起来很简单,但我无法弄清楚。
        • 很酷的东西!但是为什么你需要括号内的 None 呢?
        • @FerdinandoRandisi 这就是我指定我希望跨多行广播操作的方式:)
        猜你喜欢
        • 1970-01-01
        • 2020-01-04
        • 2017-03-06
        • 1970-01-01
        • 1970-01-01
        • 2015-05-28
        • 1970-01-01
        • 2021-08-21
        • 2015-01-29
        相关资源
        最近更新 更多