Как заменить только часть значений массива numpy значениями другого массива?

Я пытаюсь сделать что-то вроде замаскированной трансляции, когда транслируются только определенные значения.

Предположим, у меня есть один больший массив, big_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]

также бесполезен, так как это сглаживает массив, делая вещание несовместимым.

Возможно, есть какой-то другой способ добиться того же эффекта?


person JtD    schedule 19.12.2015    source источник


Ответы (2)


Вы были рядом, когда у вас было -

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)
person Divakar    schedule 19.12.2015

На самом деле можно использовать numpy.where с вашей маской в ​​качестве условия и заполнить это с smaller_array, когда условие истинно. Кстати, IIUC вы могли бы использовать 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)

Затем вы можете назначить это для своей переменной

person Anton Protopopov    schedule 19.12.2015