Изменение массива с помощью массива индексов
Есть два массива: один массив индексов, другой — массив элементов.
Хочу в массиве элементов изменить элементы (к примеру, вычесть 1), которые соответствуют индексам, находящимися в массиве индексов (без циклов).
К примеру (на вычитание 1):
Исходные данные:
array1 = [[1, 2, 3, 4], [10, 11, 12, 13]], indexes = [[1], [3]]
Ожидаемый результат:
array1 = [[1, 1, 3, 4], [10, 11, 12, 12]]
Ответы (2 шт):
Автор решения: MaxU
→ Ссылка
Пример:
In [113]: a1 = np.array(array1)
In [114]: idx = np.array(indexes).ravel()
In [115]: a1
Out[115]:
array([[ 1, 2, 3, 4],
[10, 11, 12, 13]])
In [116]: idx
Out[116]: array([1, 3])
решение:
In [117]: a1[np.arange(len(idx)), idx] -= 1
результат:
In [118]: a1
Out[118]:
array([[ 1, 1, 3, 4],
[10, 11, 12, 12]])
Автор решения: MiniMax
→ Ссылка
Если в образовательных целях установлено искусственное ограничение не использовать конструкции for, while, то можно сделать так:
array1 = [[1, 2, 3, 4], [10, 11, 12, 13]]
indexes = [[1, 2], [2, 3]] # добавил индексов для наглядности
list(map(lambda tup: list(map(lambda idx: tup[0].__setitem__(idx, tup[0][idx] - 1), tup[1])), zip(array1, indexes)))
print(array1)
Output
[[1, 1, 2, 4], [10, 11, 11, 12]]
Читаемая версия
list(map(
lambda tup: list(map( # tup - кортеж вида: (значения, индексы), полученный
# с помощью zip()
# tup[0] - список со значениями, которые нужно изменить
lambda idx: tup[0].__setitem__(idx, tup[0][idx] - 1),
tup[1] # список с индексами
)
),
zip(array1, indexes)
)
)
Но конечно, с циклом намного проще:
for lst, idxs in zip(array1, indexes):
for i in idxs:
lst[i] -= 1