代码之家  ›  专栏  ›  技术社区  ›  Max Collier

当应用相同形状的遮罩时,numpy数组丢失维度

  •  1
  • Max Collier  · 技术社区  · 7 年前

    我已经创建了一个名为 mask 与数组形状相同 data ,我要应用它的数组。但是,当我这样做时,数据会丢失形状并变为1d。

    我认为轴0的每个级别都是相同的(如 面具 使用循环理解)输出将生成具有形状的输出 (837, 10)

    我想知道,在不使用“重塑”的情况下,是否有一些麻木的技巧可以用来实现这一目标?

    >>> data.shape
    (837, 44)
    
    >>> m = altitudes < 50000
    >>> m.shape
    (44,)
    
    >>> np.sum(m) # calculates my expected dimension for axis 1
    10
    
    >>> mask = [m for i in range(data.shape[0])]
    >>> mask.shape
    (837, 44)
    
    >>> new_data = data[mask]
    >>> new_data.shape
    (8370,) # same as 837 * 10 (dimension wanted)
    

    如果这不能实现,为什么会这样?

    干杯

    2 回复  |  直到 7 年前
        1
  •  3
  •   Paul Panzer    7 年前

    实现目标的“正确”方法是不要将遮罩扩展到2d。 [:, mask] 带1d面罩。这表示您希望轴0保持不变,并且 mask 沿轴1应用。

    a = np.arange(12).reshape(3, 4)
    b = np.array((1,0,1,0),'?')
    a
    # array([[ 0,  1,  2,  3],
    #        [ 4,  5,  6,  7],
    #        [ 8,  9, 10, 11]])
    b
    # array([ True, False,  True, False])
    a[:, b]
    # array([[ 0,  2],
    #        [ 4,  6],
    #        [ 8, 10]])
    

    如果你 面具 已经是2d了,numpy不会检查它的所有行是否相同,因为这样效率会很低。但显然你可以用 [:, mask[0]] 那样的话。

    如果你 面具 是二维的,正好有相同数量的 True 在每一行中,然后使用@tel的答案。或创建索引数组:

    B = b^b[:3, None]
    B
    # array([[False,  True, False,  True],
    #        [ True, False,  True, False],
    #        [False,  True, False,  True]])
    J = np.where(B)[1].reshape(len(B), -1)
    

    现在也不是

    np.take_along_axis(a, J, 1)
    # array([[ 1,  3],
    #        [ 4,  6],
    #        [ 9, 11]])
    

    I = np.arange(len(J))[:, None]
    IJ = I, J
    a[IJ]
    # #array([[ 1,  3],
    #         [ 4,  6],
    #         [ 9, 11]])
    
        2
  •  1
  •   tel    7 年前

    我相信你想做的事可以通过打电话 new_data.reshape(837, -1) . 下面是一个简单的例子:

    arr = np.arange(8*6).reshape(8,6)
    maskpiece = np.array([True, False]*3)
    mask = np.broadcast_to(maskpiece, (8,6))
    
    print('the original array\n%s\n' % arr)
    print('the flat masked array\n%s\n' % arr[mask])
    print('the masked array reshaped into 2D\n%s\n' % arr[mask].reshape(8, -1))
    

    输出:

    the original array
    [[ 0  1  2  3  4  5]
     [ 6  7  8  9 10 11]
     [12 13 14 15 16 17]
     [18 19 20 21 22 23]
     [24 25 26 27 28 29]
     [30 31 32 33 34 35]
     [36 37 38 39 40 41]
     [42 43 44 45 46 47]]
    
    the flat masked array
    [ 0  2  4  6  8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46]
    
    the masked array reshaped into 2D
    [[ 0  2  4]
     [ 6  8 10]
     [12 14 16]
     [18 20 22]
     [24 26 28]
     [30 32 34]
     [36 38 40]
     [42 44 46]]