Ответ 1
Выборы или назначения с np.ix_
с индексированием или логическими массивами/масками
1. С indexing-arrays
А. Выбор
Мы можем использовать np.ix_
для получения np.ix_
индексных массивов, которые могут транслироваться друг против друга, что приводит к многомерным комбинациям индексов. Таким образом, когда этот кортеж используется для индексации во входном массиве, мы получим тот же самый многомерный массив. Следовательно, чтобы сделать выборку на основе двух 1D
индексных массивов, было бы:
x_indexed = x[np.ix_(row_indices,col_indices)]
Б. Назначение
Мы можем использовать одну и ту же запись для присвоения скалярного или широковещательного массива этим индексированным позициям. Следовательно, следующие работы для заданий -
x[np.ix_(row_indices,col_indices)] = # scalar or broadcastable array
2. с masks
Мы также можем использовать логические массивы/маски с np.ix_
, аналогично тому, как используются индексные массивы. Это можно использовать снова, чтобы выбрать блок из входного массива, а также для назначений в нем.
А. Выбор
Таким образом, с булевыми массивами row_mask
и col_mask
в качестве масок для выбора строк и столбцов соответственно, мы можем использовать следующее для выбора:
x[np.ix_(row_mask,col_mask)]
Б. Назначение
И следующие работы для заданий -
x[np.ix_(row_mask,col_mask)] = # scalar or broadcastable array
Пробные прогоны
Использование np.ix_
с indexing-arrays
Входной массив и индексные массивы -
In [221]: x
Out[221]:
array([[17, 39, 88, 14, 73, 58, 17, 78],
[88, 92, 46, 67, 44, 81, 17, 67],
[31, 70, 47, 90, 52, 15, 24, 22],
[19, 59, 98, 19, 52, 95, 88, 65],
[85, 76, 56, 72, 43, 79, 53, 37],
[74, 46, 95, 27, 81, 97, 93, 69],
[49, 46, 12, 83, 15, 63, 20, 79]])
In [222]: row_indices
Out[222]: [4, 2, 5, 4, 1]
In [223]: col_indices
Out[223]: [1, 2]
Кортеж индексных массивов с помощью np.ix_
-
In [224]: np.ix_(row_indices,col_indices) # Broadcasting of indices
Out[224]:
(array([[4],
[2],
[5],
[4],
[1]]), array([[1, 2]]))
Сделайте выбор -
In [225]: x[np.ix_(row_indices,col_indices)]
Out[225]:
array([[76, 56],
[70, 47],
[46, 95],
[76, 56],
[92, 46]])
Как предложено OP, это в действительности то же самое, что выполнение вещания старой школы с версией двумерного массива row_indices
, элементы/индексы которого отправляются по axis=0
и, таким образом, создается одноэлементное измерение на axis=1
что позволяет осуществлять вещание с col_indices
, Таким образом, у нас было бы альтернативное решение, как так -
In [227]: x[np.asarray(row_indices)[:,None],col_indices]
Out[227]:
array([[76, 56],
[70, 47],
[46, 95],
[76, 56],
[92, 46]])
Как уже говорилось ранее, для заданий мы просто делаем это.
Row, col, индексация массивов -
In [36]: row_indices = [1, 4]
In [37]: col_indices = [1, 3]
Делать задания со скаляром -
In [38]: x[np.ix_(row_indices,col_indices)] = -1
In [39]: x
Out[39]:
array([[17, 39, 88, 14, 73, 58, 17, 78],
[88, -1, 46, -1, 44, 81, 17, 67],
[31, 70, 47, 90, 52, 15, 24, 22],
[19, 59, 98, 19, 52, 95, 88, 65],
[85, -1, 56, -1, 43, 79, 53, 37],
[74, 46, 95, 27, 81, 97, 93, 69],
[49, 46, 12, 83, 15, 63, 20, 79]])
Делать назначения с 2D блоком (транслируемый массив) -
In [40]: rand_arr = -np.arange(4).reshape(2,2)
In [41]: x[np.ix_(row_indices,col_indices)] = rand_arr
In [42]: x
Out[42]:
array([[17, 39, 88, 14, 73, 58, 17, 78],
[88, 0, 46, -1, 44, 81, 17, 67],
[31, 70, 47, 90, 52, 15, 24, 22],
[19, 59, 98, 19, 52, 95, 88, 65],
[85, -2, 56, -3, 43, 79, 53, 37],
[74, 46, 95, 27, 81, 97, 93, 69],
[49, 46, 12, 83, 15, 63, 20, 79]])
Использование np.ix_
с masks
Входной массив -
In [19]: x
Out[19]:
array([[17, 39, 88, 14, 73, 58, 17, 78],
[88, 92, 46, 67, 44, 81, 17, 67],
[31, 70, 47, 90, 52, 15, 24, 22],
[19, 59, 98, 19, 52, 95, 88, 65],
[85, 76, 56, 72, 43, 79, 53, 37],
[74, 46, 95, 27, 81, 97, 93, 69],
[49, 46, 12, 83, 15, 63, 20, 79]])
Ввод строки, масок col -
In [20]: row_mask = np.array([0,1,1,0,0,1,0],dtype=bool)
In [21]: col_mask = np.array([1,0,1,0,1,1,0,0],dtype=bool)
Сделайте выбор -
In [22]: x[np.ix_(row_mask,col_mask)]
Out[22]:
array([[88, 46, 44, 81],
[31, 47, 52, 15],
[74, 95, 81, 97]])
Делать задания со скаляром -
In [23]: x[np.ix_(row_mask,col_mask)] = -1
In [24]: x
Out[24]:
array([[17, 39, 88, 14, 73, 58, 17, 78],
[-1, 92, -1, 67, -1, -1, 17, 67],
[-1, 70, -1, 90, -1, -1, 24, 22],
[19, 59, 98, 19, 52, 95, 88, 65],
[85, 76, 56, 72, 43, 79, 53, 37],
[-1, 46, -1, 27, -1, -1, 93, 69],
[49, 46, 12, 83, 15, 63, 20, 79]])
Делать назначения с 2D блоком (транслируемый массив) -
In [25]: rand_arr = -np.arange(12).reshape(3,4)
In [26]: x[np.ix_(row_mask,col_mask)] = rand_arr
In [27]: x
Out[27]:
array([[ 17, 39, 88, 14, 73, 58, 17, 78],
[ 0, 92, -1, 67, -2, -3, 17, 67],
[ -4, 70, -5, 90, -6, -7, 24, 22],
[ 19, 59, 98, 19, 52, 95, 88, 65],
[ 85, 76, 56, 72, 43, 79, 53, 37],
[ -8, 46, -9, 27, -10, -11, 93, 69],
[ 49, 46, 12, 83, 15, 63, 20, 79]])