2016-12-21 12 views
3

Итак, фоном этой «проблемы» является то, что я пытаюсь оптимизировать большой проект python. Я начал приурочивать программу и заметил, что почти 50% времени выполнения тратится на расчет, подобный этому:Numpy: Эффективный расчет матрицы A * xj где xj - это строка j в X

import numpy as np 

# Example 
A = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]]) 
X = np.random.multivariate_normal([0,0,0,0],np.eye(4),15000) 

# Create a lambda function to use row based 
F = lambda x: np.dot(A,x) 

# Now calculating the value 
answer = np.apply_along_axis(F, 1, X) 

print answer.shape 

Я пытался найти способ, чтобы сделать это быстрее, но продолжает работать в стены. Действительно ли это оптимально для этого?

ответ

5

Мы можем использовать np.dot на X и A, чтобы потерять их вторую ось. Для ввода в np.dot мы будем использовать X в качестве первого входа и транспонируем A, чтобы перенести свою вторую ось на фронт, которая будет использоваться в качестве второго входа.

Таким образом, мы имели бы выход, как так -

X.dot(A.T) 

время выполнения теста для выборки входов, перечисленных в вопросе -

In [192]: %timeit np.apply_along_axis(F, 1, X) 
1 loops, best of 3: 185 ms per loop 

In [193]: %timeit X.dot(A.T) 
1000 loops, best of 3: 228 µs per loop 

In [194]: np.allclose(np.apply_along_axis(F, 1, X), X.dot(A.T)) 
Out[194]: True # verified results against original code 
+1

Wow! Это потрясающее увеличение скорости! Я свяжусь с этим ответом в коде, спасибо :) – Dammi

+0

@piRSquared Эй! Ну, я видел, что раньше, и точки, которые там были, имеют смысл для меня, мне это уже понравилось :) Думаю, я думал о том, чтобы указать на 'np.take', который помогает, если у вас много повторяющихся индексов. Этот момент был сделан там @hpaulj в связанных комментариях и комментариях, которые я предполагаю. Таким образом, во всем этом Q & A наряду с комментариями делает дискуссию по теме довольно всеобъемлющей. Хорошая работа по исследованию этих вещей! – Divakar

+0

@ Дивакар спасибо – piRSquared