Распределение точек по точкам в Python [дубликат]

3
задан Hendrik Wiese 9 March 2016 в 16:09
поделиться

2 ответа

То, что dot-product существенно выполняет редукцию вдоль axis=1 двух входных массивов. Размеры могут быть представлены так:

arr_in   :     n   3 
matrices : n   3   3

. Таким образом, одним из способов его решения было бы «нажимать» размеры arr_in вперед на один axis/dimension, создавая таким образом одноэлементное измерение в axis=2 в версии 3D-массива. Тогда сумма, уменьшающая элементы вдоль axis = 1, даст нам желаемый результат. Покажем это -

arr_in   : n   [3]   1 
matrices : n   [3]   3

Теперь это может быть достигнуто двумя способами.

1) С помощью np.einsum -

np.einsum('ij,ijk->ik',arr_in,matrices)

2) С помощью NumPy broadcasting -

(arr_in[...,None]*matrices).sum(1)

Проверка времени выполнения и проверка вывода (для версии einsum) -

In [329]: def loop_based(arr_in,matrices):
     ...:     arr_out = np.zeros((arr_in.shape[0], 3))
     ...:     for i in range(arr_in.shape[0]):
     ...:         arr_out[i] =  np.dot(arr_in[i], matrices[i])
     ...:     return arr_out
     ...: 
     ...: def einsum_based(arr_in,matrices):
     ...:     return np.einsum('ij,ijk->ik',arr_in,matrices)
     ...: 

In [330]: # Inputs
     ...: N = 16935
     ...: arr_in = np.random.randn(N, 3)
     ...: matrices = np.random.randn(N, 3, 3)
     ...: 

In [331]: np.allclose(einsum_based(arr_in,matrices),loop_based(arr_in,matrices))
Out[331]: True

In [332]: %timeit loop_based(arr_in,matrices)
10 loops, best of 3: 49.1 ms per loop

In [333]: %timeit einsum_based(arr_in,matrices)
1000 loops, best of 3: 714 µs per loop
1
ответ дан Divakar 26 August 2018 в 06:47
поделиться

Вы можете использовать np.einsum . Чтобы получить v.dot(M) для каждой пары вектор-матрица, используйте np.einsum("...i,...ij", arr_in, matrices). Чтобы получить M.dot(v), используйте np.einsum("...ij,...i", matrices, arr_in)

0
ответ дан Bill 26 August 2018 в 06:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: