#python-3.x #numpy #numpy-ndarray
#python-3.x #numpy #numpy-ndarray
Вопрос:
Существует ли эффективное решение на основе «Numpy» для создания 3-х (или более высокой) размерной диагональной матрицы?
Более конкретно, я ищу более короткое (и, возможно, более эффективное) решение для замены следующего:
N = 100
M = 4
d = np.random.randn(N) # calculated in the real use case from other parameters
A = np.zeros(M, M, N, dtype=d.dtype)
for i in range(M):
A[i, i, :] = d
Вышеупомянутое решение будет медленным, если M
оно большое, и я думаю, что оно не очень экономично с точки зрения памяти, поскольку d
оно копируется M
раз в памяти.
Ответ №1:
Вот один с np.einsum
diag-view —
np.einsum('iij->ij',A)[:] = d
Глядя на строковую нотацию, это также хорошо переводится из итеративной части : A[i, i, :] = d
.
Обобщить на ndarray с помощью ellipsis
—
np.einsum('ii...->i...',A)[:] = d
Комментарии:
1. Но это все равно требует определения
A
заранее, я прав? Я надеялся найти что-то вродеA = some_magic_function(d, M)
?2. @kMaster И выполнение инициализации
A = np.zeros((M, M, N), dtype=d.dtype)
вас беспокоит?3. Да, в основном потому, что это означает, что мы выделяем
M*M*N
элемент памяти для этого массива, тогдаN
как для хранения такого массива должно быть достаточно только элементов.4. @kMaster Вы, вероятно, хотите сохранить в разреженной матрице? К сожалению, нет ни одного для 3D или выше.