#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-массив, содержащий положительные и отрицательные значения: (