无法使用numpy将值分配给“双切片”

时间:2016-01-13 10:24:43

标签: python arrays numpy slice

如何在numpy中执行以下操作?

  1. 选择包含超过50%0值的数组的所有行。
  2. 从满足1的所有行中选择第一个n(假设为2)行。
  3. 执行某些操作,并将修改后的行放在零数组的相同索引上,其形状等于1。
  4. 以下结果是没有分配新值的数组:

    In [177]:    
    a = np.array([[0,0,3],[4,5,6],[7,0,0],[10,11,12],[13,14,15]])
    b = np.zeros_like(a)
    a
    Out[177]:    
    array([[ 0,  0,  3],
           [ 4,  5,  6],
           [ 7,  0,  0],
           [10, 11, 12],
           [13, 14, 15]])
    
    In [178]:
    # select all rows containg note more than 50% 0 values
    percent = np.sum(a == 0, axis=-1) / float(check.shape[1])
    percent = percent >= 0.5
    slice = np.invert(percent).nonzero()[0]
    
    In [183]:
    # select first two rows satisfying 'slice'
    a[slice][0:2] 
    
    Out[183]:    
    array([[ 4,  5,  6],
           [10, 11, 12]])
    
    In [182]:
    # do something and place modified rows on same index of zero array
    b[slice][0:2] = a[slice][0:2] * 2
    
    In [184]:
    b
    Out[184]:    
    array([[0, 0, 0],
           [0, 0, 0],
           [0, 0, 0],
           [0, 0, 0],
           [0, 0, 0]])
    

1 个答案:

答案 0 :(得分:7)

问题是b[slice]创建了一个副本而不是一个视图(它触发了花哨的索引)。代码b[slice][0:2]创建了此副本的视图(而不是原始b!)。因此...

b[slice][0:2] = a[slice][0:2] * 2

...将a的相应行分配给b副本的视图。

因为它可能导致这些情况,所以最好不要以这种方式链接索引操作。相反,只需先计算slice的相关行号,然后执行赋值:

slice = np.invert(percent).nonzero()[0][:2] # first two rows
b[slice] = a[slice] * 2