如何只将numpy数组的部分值替换为另一个数组的值?

时间:2015-12-19 21:26:44

标签: python arrays numpy numpy-broadcasting

我正在尝试按屏蔽广播的方式做一些事情,其中​​只播放某些值。

假设我有一个更大的数组,greater_array和一个更小的数组,small_array:

import numpy as np
import numpy.ma as ma

bigger_array = np.zeros((4,4), dtype=np.int32)
smaller_array = np.ones((2,2), dtype=np.int32)

现在,我只希望较小数组的前三个值替换较大数组的某个部分的值,但是屏蔽不能达到我希望的效果:

masked_smaller_array = ma.masked_array(smaller_array, mask=[(0, 0), (0, 1)])
bigger_array[2:4, 2:4] = masked_smaller_array 

这只会返回常规广播的相同内容,即:

[[0 0 0 0]
 [0 0 0 0]
 [0 0 1 1]
 [0 0 1 1]]

而不是我希望的

[[0 0 0 0]
 [0 0 0 0]
 [0 0 1 1]
 [0 0 1 0]]

在覆盖通过

之前删除屏蔽的值
bigger_array[2:4, 2:4] = masked_smaller_array[~masked_smaller_array.mask]

也没有用,因为这会使阵列变得平坦,使得广播不兼容。

是否还有其他方法可以达到同样的效果?

2 个答案:

答案 0 :(得分:1)

当你有 -

时,你很亲密
bigger_array[2:4, 2:4] = masked_smaller_array[~masked_smaller_array.mask]

您只需要将等式的左侧编入索引,以便在那里使用相同的蒙版。因此,解决它的一种方法是修复它,就像这样 -

# Mask corresponding to smaller array from where elements are to be taken
select_mask = ~masked_smaller_array.mask

# Use the mask on source (smaller array) to select specific elements from it 
# and update sliced and masked (with same mask) places in bigger array
bigger_array[2:4, 2:4][select_mask] = smaller_array[select_mask]

示例运行 -

In [59]: bigger_array = np.zeros((4,4), dtype=np.int32)
    ...: smaller_array = np.ones((2,2), dtype=np.int32)
    ...: masked_smaller_array =ma.masked_array(smaller_array,mask=[(0, 0),(0, 1)])
    ...: 

In [60]: select_mask = ~masked_smaller_array.mask

In [61]: select_mask
Out[61]: 
array([[ True,  True],
       [ True, False]], dtype=bool)

In [62]: bigger_array[2:4, 2:4][select_mask] = smaller_array[select_mask]

In [63]: bigger_array
Out[63]: 
array([[0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 1, 1],
       [0, 0, 1, 0]], dtype=int32)

答案 1 :(得分:0)

实际上可以使用numpy.where将掩码作为条件,并在条件为真时用smaller_array填充它。顺便说一句,您可以使用make_mask代替masked_array来实现此目的:

your_mask = [(0, 0), (0, 1)]
mask = ma.make_mask(your_mask)
np.where(~mask, smaller_array, bigger_array[2:4, 2:4])


In [106]: mask
Out[106]: 
array([[False, False],
       [False,  True]], dtype=bool)

In [108]: np.where(~mask, smaller_array, bigger_array[2:4, 2:4])
Out[108]: 
array([[1, 1],
       [1, 0]], dtype=int32)

然后你可以为你的变量指定