numpy, где условие по индексу

#python #numpy

Вопрос:

У меня есть массив чисел numpy 1D,представляющих столбцы, например: [0,0,2,1] И матрицу, например:

 [[1,1,1],
[1,1,1],
[1,1,1],
[1,1,1]]
 

Теперь я хочу изменить значения в матрице на 0, где индекс столбца больше, чем значение, заданное в массиве 1D:

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

 

Как я могу этого достичь? Я думаю, что мне нужно условие, основанное на индексе, а не на значении

Пояснение: Первая строка в матрице имеет индексы [0,0 ; 0,1 ; 0,2], где вторым индексом является столбец. Для индексов 0,0 ; 0,1 и 0,2 задается значение 0. 1 и 2 больше 0. Таким образом, только 0,0 не изменяется на ноль.

Комментарии:

1. Индекс столбца (2) больше, чем все значения в столбце с индексом 2. Почему бы тебе тогда не сменить все 1 на 0?

2. @zabop, где индекс столбца больше, для первой строки [1,1,1] у нас есть число 0. В этой строке у нас есть числа с индексами 0,0 ; 0,1 и 0,2. Первый индекс не имеет столбца >0, остальные имеют. 1 и 2 из 0,1 и 0,2 больше 0.

Ответ №1:

Предполагая a 2D массив и v 1D вектор, вы можете создать маску того же размера и использовать numpy.where :

 x,y = a.shape
np.where(np.tile(np.arange(y), (x,1)) <= v[:,None], a, 0)
 

Ввод:

 a = np.array([[1,1,1],
              [1,1,1],
              [1,1,1],
              [1,1,1]])

v = np.array([0,0,2,1])
 

Выход:

 array([[1, 0, 0],
       [1, 0, 0],
       [1, 1, 1],
       [1, 1, 0]])
 

Промежуточные продукты:

 >>> np.tile(np.arange(y), (x,1))
[[0 1 2]
 [0 1 2]
 [0 1 2]
 [0 1 2]]

>>> np.tile(np.arange(y), (x,1)) <= v[:,None]
[[ True False False]
 [ True False False]
 [ True  True  True]
 [ True  True False]]
 

Комментарии:

1. Спасибо за ваш ответ, это работает! Я принял ваш ответ за четкие детали, простые два лайнера и четкие промежуточные шаги.

Ответ №2:

Постройте 2D-массив, элементы которого являются соответствующим индексом столбца, а затем замаскируйте элементы, превышающие соответствующее значение 1D-массива.

Воспользовавшись преимуществами вещания, вы можете сделать:

 >>> arr = np.ones((4,3))
>>> arr 

array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])

>>> col_thr_idx = np.array([0,0,2,1])
>>> col_thr_idx

array([0, 0, 2, 1])

>>> mask = np.arange(arr.shape[1])[None,:] > col_thr_idx[:,None]
>>> mask

array([[False,  True,  True],
       [False,  True,  True],
       [False, False, False],
       [False, False,  True]])

>>> arr[mask] = 0
>>> arr

array([[1., 0., 0.],
       [1., 0., 0.],
       [1., 1., 1.],
       [1., 1., 0.]])