Умножение 2D и 1D массивов NumPy

#python #arrays #performance #numpy #product

#python #массивы #Производительность #numpy #продукт

Вопрос:

Я немного новичок в python и numpy, поэтому, возможно, кто-то из вас сможет мне здесь помочь.

У меня есть 1D массив numpy с именем z и некоторые 2D матрицы с именами X0, Y0 и SLM.

Я хочу создать 3D-массив (стек 2D-матриц), выполнив эту операцию, пытаясь избежать цикла for:

 for index in range(len(z)):
    3D_array[index] = SLM * np.exp( z[index] * (X0 Y0) )
  

До сих пор я пытался:

3D_array = SLM[np.newaxis, :] * np.exp( z[:, np.newaxis, np.newaxis] * (X0 Y0))

Это работает правильно, но для моих целей медленно. Массивы большие (z имеет размер 200, а все 2D-матрицы имеют размер 1024×1024)

Знаете ли вы какую-нибудь более быструю реализацию для этого?

Ответ №1:

Хороший вопрос, который вы ищете np.tensordot , см. Пример ниже:

 import numpy as np

x0 = np.floor(np.random.rand(3, 3)*10)
y0 = np.floor(np.random.rand(3, 3)*10)

z = np.array([1, 2, 3])

SLM = 1

array = SLM*np.exp(np.tensordot(z, x0 y0, axes=0))
  

Комментарии:

1. Полезно в последнем продукте, однако SLM — это 2D (сложный) массив. Мое узкое место лежит на первом продукте, SLM (расширен до 3D-массива) * np.exp(…) (также расширен до 3D-массива)

Ответ №2:

 # Assuming SLM contains only positive values this is the fastest way 
%timeit np.log(slm[np.newaxis, :, :]   1e-9)   z[:, np.newaxis, np.newaxis] * (x   y )
1.67 s ± 11 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

 %timeit slm[np.newaxis, :, :] * np.exp(z[:, np.newaxis, np.newaxis] * (x   y ))
4.15 s ± 689 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit slm[np.newaxis, :, :] * np.exp(np.tensordot(z, x   y, axes=0))
3.9 s ± 43.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
  

Комментарии:

1. к сожалению, SLM представляет собой сложный 2D-массив, содержащий положительные и отрицательные значения: (