#python #numpy #vectorization
Вопрос:
Я ищу векторизованную форму следующего вычисления:
import numpy as np D = 100 N = 1000 K = 10 X = np.random.uniform(0, 1, (K, N)) T = np.random.uniform(0, 1000, (D, N)) out = np.zeros((D, K)) for i in range(D): for j in range(K): out[i, j] = np.prod(X[j, :] ** T[i, :])
Есть вещи в стиле эйнсум, которые я пробовал, но присутствие np.prod меня немного сбивает с толку.
ПРАВКА: Уменьшен размер матриц.
Комментарии:
1. Можете ли вы привести более минимальный пример? У меня нет 80 ГБ памяти, которая валяется где попало.
2. Ваш код просто приводит ко всем нулям для меня. Являются ли это фактическими входными данными?
3. Это нормально; до тех пор, пока выражение правильное. Минимальный пример предназначен для функциональности, а не для утилиты (я не могу загрузить свои исходные матрицы здесь).
4. Похоже, тебе может понадобиться
(X ** T[:, None]).prod(-1)
5. @пользователь3483203. Вы можете уменьшить любой из размеров, не повредив концепции…
Ответ №1:
Я пытаюсь сделать трансляцию как можно более явной — None
вводится дополнительное фиктивное измерение размера 1:
out = np.prod(X[None, :, :] ** T[:, None, :], axis=2)
Легко увидеть , как это работает, если мы вспомним формы: X.shape = (K, N)
, T.shape = (D, N)
и out.shape = (D, K)
. С фиктивным измерением мы в основном берем что-то из (1, K, N)
того, к (D, 1, N)
чему приводит сила (D, K, N)
. Наконец, если мы уменьшим через продукт по последнему измерению, мы получим желаемый результат (D, K)
.