代码之家  ›  专栏  ›  技术社区  ›  James Schinner

指定给2D NumPy数组的切片

  •  1
  • James Schinner  · 技术社区  · 8 年前

    我想分配 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
    
    4 回复  |  直到 8 年前
        1
  •  5
  •   cs95 abhishek58g    8 年前

    您可以使用广播比较生成掩码,并将其索引到 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]])
    
        2
  •  1
  •   Ferdinando Randisi    8 年前

    这就是诀窍:

    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
    
        3
  •  1
  •   berna1111    8 年前
    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
    
        4
  •  1
  •   Paul Panzer    8 年前

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

    >>> 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重复每个数字来填充相应的切片。

    列索引从零开始,大部分时间递增1。所以,为了构造它们,我们在大多数情况下使用cumsum。只有在每一行的开头,我们才需要重置。我们通过减去相应切片的长度来实现这一点,例如取消我们在该行中求和的长度。