Я погуглил, спросил
Предположим, у меня есть 4-мерный массив — в данном случае формы (3, 2, 2, 2):
a = np.array([
[[[0, 0], [0, 0]],
[[0, 0], [0, 0]]],
[[[0, 0], [0, 0]],
[[0, 0], [0, 0]]],
[[[0, 0], [0, 0]],
[[0, 0], [0, 0]]],
])
и я хочу установить для последнего (второго) элемента последнего измерения другое значение в соответствии с каждой строкой первого измерения. В моем примере у меня есть 3 строки в первом измерении, поэтому предположим, что я хочу применить значения [1, 2, 3], чтобы получить:
[
[[[0, 1], [0, 1]],
[[0, 1], [0, 1]]],
[[[0, 2], [0, 2]],
[[0, 2], [0, 2]]],
[[[0, 3], [0, 3]],
[[0, 3], [0, 3]]],
]
Самый близкий синтаксис, о котором я смог подумать, был бы:
a[:, ..., 1] = [1, 2, 3]
Но выдает ошибку (ValueError: could not broadcast input array from shape (3,) into shape (3,2,2)
). Никакой ошибки не возникнет, если я попытаюсь:
a[:, ..., 1] = [1, 2]
но это дает другой результат, а это не то, что я хочу:
a = np.array([
[[[0, 1], [0, 2]],
[[0, 1], [0, 2]]],
[[[0, 1], [0, 2]],
[[0, 1], [0, 2]]],
[[[0, 1], [0, 2]],
[[0, 1], [0, 2]]],
])
Есть ли способ элегантно и компактно сделать то, что я хочу?
На данный момент я написал цикл для циклического обхода каждой строки первого измерения и затем установки значений для каждой строки, но мне интересно, есть ли более мощный способ сделать это в одной строке.
Вам необходимо предоставить массив 3-1-1 в правой части задания, чтобы numpy мог транслировать его в форму 3-2-2 вашего среза. Если я правильно понял ваш запрос, следующее выражение будет работать
a[:, ..., 1] = np.array([1, 2, 3])[:, None, None]
Спасибо, это именно то, что я искал! Теперь я понимаю, как это работает концептуально. И, как заметил Бен Гроссман, левая часть может быть просто [a..., 1] — двоеточие лишнее.
Кстати, между
a[:, ..., 1]
иa[..., 1]
нет никакой разницы.