2015-01-07 1 views
3

У меня есть большой набор матриц 3 x 3 (скажем, n) и соответствующие векторы 3 x 1 и хотели бы умножить каждый вектор на соответствующую ему матрицу. Если укладываю матрицы в n х 3 х 3 ndarray называется R и векторы в 3 х nndarray называется v, я могу получить пачку размноженных векторов через,Изготовление срезов точечного вывода без промежуточных продуктов

import numpy as np 
intermediate = np.dot(R, v) 
out = np.diagonal(intermediate, axis1=0, axis2=2) 

Но это очень неэффективно: np.dot производит массив n x 3 x nintermediate, из которого я вручную выбираю 3 x n фрагмент. Могу ли я каким-то образом создать массив 3 x n, не сделав промежуточным n x 3 x n массив?

+3

Посмотрите на 'np.einsum'. – hpaulj

+0

@MattDMo, это не позволяет генерировать промежуточный массив. Он просто избегает присвоения ему имени. Но он по-прежнему занимает память и требует вычисления. –

+0

Я все еще немного новичок в новинке - как я уже сказал, дикое предположение :) – MattDMo

ответ

5

Расширение на подсказку, представленной @hpaulj: умножение я описывала может быть осуществлено,

out = np.einsum('ijk,ki->ji', R, v) 

Ускорение по подходу в моем вопросе уже 3 порядков для n = 1000 (!):

%timeit d = np.diagonal(np.dot(R, v), axis1=0, axis2=2) 
10 loops, best of 3: 27.8 ms per loop 

%timeit o = np.einsum('ijk,ki->ji', R, v) 
10000 loops, best of 3: 21.9 µs per loop 
+2

Когда-то в не столь отдаленном будущем, используя Python 3.5 и предстоящую версию numpy, вы могли бы сделать: 'out = R @ vT [:, None,:] ', см. [Здесь] (https://www.python.org/dev/peps/pep-0465/). – Jaime

Смежные вопросы