#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.]])