#python #numpy #numpy-ndarray
#python #numpy #numpy-ndarray
Вопрос:
У меня есть ndarray с формой (3,3,3) и список с 3 числами.
Я хочу разделить первое измерение на первое число в списке, второе измерение на второе число и третье измерение на третье число.
Пример:
np.random.rand(3,3,3)
>>>array([[[0.90428811, 0.60637664, 0.45090308],
[0.17400851, 0.49163535, 0.62370288],
[0.58701608, 0.91207839, 0.69364496]],
[[0.85290321, 0.85170489, 0.48792597],
[0.02602198, 0.91088298, 0.14882673],
[0.63354821, 0.21764451, 0.30760075]],
[[0.64833375, 0.13583598, 0.50561519],
[0.42832468, 0.91146014, 0.41627495],
[0.71238947, 0.37868578, 0.05874898]]])
и список:
lst=[0.215, 0.561,0.724]
Я хочу, чтобы результат вывода был результатом этого:
[0.90428811/0.215, 0.60637664/0.215, 0.45090308/0.215],
[0.17400851/0.215, 0.49163535/0.215, 0.62370288/0.215],
[0.58701608/0.215, 0.91207839/0.215, 0.69364496/0.215]],
[[0.85290321/0.561, 0.85170489/0.561, 0.48792597/0.561],
[0.02602198/0.561, 0.91088298/0.561, 0.14882673/0.561],
[0.63354821/0.561, 0.21764451/0.561, 0.30760075/0.561]],
[[0.64833375/0.724, 0.13583598/0.724, 0.50561519/0.724],
[0.42832468/0.724, 0.91146014/0.724, 0.41627495/0.724],
[0.71238947/0.724, 0.37868578/0.724, 0.05874898/0.724]]])
Я пытался сделать что-то подобное (arr — это ndarray).:
nums=np.arange(3)
for n in nums:
arr[i]=arr[i]/lst[i]
но получил ошибку:
Ошибка IndexError: допустимыми индексами являются только целые числа, срезы (
:
), многоточие (...
), numpy.newaxis (None
) и целочисленные или логические массивы
Комментарии:
1. Возможно, вы сможете сделать это с помощью einsum
Ответ №1:
Просто сделайте это. Он передает lst
массив, чтобы иметь форму (3, 1, 1)
, которая легко сочетается с формой a
.
Обратите внимание, что None
это просто псевдоним для np.newaxis
.
import numpy as np
a = np.random.randn(3,3,3)
lst = np.array([0.215, 0.561,0.724])
a / lst[:, None, None]
Комментарии:
1. это сработало! единственное, что я не уверен, что понял, это то, как он не делит все измерения на числа в lst, как он узнает, чтобы «применить» его к правильному измерению
2. Я прикрепил ссылку на numpy broadcasting в своем ответе. По сути, он виртуально копирует элементы для создания
lst
массива формы(3, 3, 3)
(3, 1, 1)
для выполнения поэлементного деления. Вы можете заглянуть по ссылке, чтобы узнать больше о том, как работает вещание, и привести больше примеров. Не стесняйтесь обращаться за дальнейшими разъяснениями.
Ответ №2:
Используйте широковещательную передачу индекса:
a = np.random.rand(3,3,3)
res = a / lst[:, np.newaxis, np.newaxis]
Причина, по которой это работает, заключается в том, что lst[:, np.newaxis, np.newaxis]
генерируется массив с формой (3, 1, 1), а numpy расширяет любое измерение размером один до требуемого размера (путем повторения элемента) для многих распространенных операций. Этот процесс называется широковещательной передачей.
Итак, в нашем примере здесь для деления результат lst[:, np.newaxis, np.newaxis]
будет расширен до:
[[[0.215, 0.215, 0.215],
[0.215, 0.215, 0.215],
[0.215, 0.215, 0.215]],
[[0.561, 0.561, 0.561],
[0.561, 0.561, 0.561],
[0.561, 0.561, 0.561]],
[[0.724, 0.724, 0.724],
[0.724, 0.724, 0.724],
[0.724, 0.724, 0.724]]]
Обратите внимание, что это расширение происходит только концептуально, и numpy не будет выделять больше памяти только для того, чтобы снова и снова заполнять ее одним и тем же значением.
Ответ №3:
Это не очень красивое решение (из-за lst
объявления), но оно работает:
import numpy as np
np.random.rand(3,3,3)
arr = np.array([[[0.90428811, 0.60637664, 0.45090308],
[0.17400851, 0.49163535, 0.62370288],
[0.58701608, 0.91207839, 0.69364496]],
[[0.85290321, 0.85170489, 0.48792597],
[0.02602198, 0.91088298, 0.14882673],
[0.63354821, 0.21764451, 0.30760075]],
[[0.64833375, 0.13583598, 0.50561519],
[0.42832468, 0.91146014, 0.41627495],
[0.71238947, 0.37868578, 0.05874898]]])
lst = [[[0.215]], [[0.561]],[[0.724]]]
div = np.divide(arr, lst)
print(div)
Вывод будет:
[[[4.20599121 2.82035647 2.09722363]
[0.80934191 2.28667605 2.90094363]
[2.73030735 4.24222507 3.22625563]]
[[1.52032658 1.51819053 0.86974326]
[0.04638499 1.62367733 0.26528829]
[1.12931945 0.38795813 0.54830793]]
[[0.8954886 0.18761876 0.69836352]
[0.59160867 1.25892285 0.5749654 ]
[0.98396336 0.52304666 0.081145 ]]]