Вы можете улучшить производительность здесь, используя широковещательную рассылку с:
p = (Z - stz[:,None]) / ((Z - stz[:,None])**2 + (X - stx[:,None])**2 + (Y - sty[:,None])**2) ** (3/2)
Обратите внимание, что повышение производительности здесь будет за счет эффективности памяти, как отметил Джером. .
Проверьте и время, используя вместо этого:
x = np.arange(0, 121, dx)
y = np.arange(0, 101, dy)
z = np.arange(20, 51, dz)
def op():
p = np.zeros((len(stx), len(X)))
for i in range(len(X)):
for j in range(len(stx)):
p[j, i] = (Z[i] - stz[j]) / ((Z[i] - stz[j]) ** 2 + (X[i] - stx[j]) ** 2 + (Y[i] - sty[j]) ** 2) ** (3/2)
return p
def ap_1():
return (Z - stz[:,None]) / ((Z - stz[:,None])**2 + (X - stx[:,None])**2 + (Y - sty[:,None])**2) ** (3/2)
%timeit p = op()
# 44.5 ms ± 3.58 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit p_ = ap_1()
# 169 µs ± 2.27 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
np.allclose(p_, p)
# True
Мы можем еще больше повысить производительность и повысить эффективность памяти, позволив numexpr
занять забота об арифметике c:
import numexpr as ne
def ap_2():
return ne.evaluate('(Z - stz2D) / ((Z - stz2D)**2 + (X - stx2D)**2 + (Y - sty2D)**2) ** (3/2)',
{'stz2D':stz[:,None], 'stx2D':stx[:,None], 'sty2D':sty[:,None]})
%timeit ap_2()
# 106 µs ± 6.34 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Итак, при втором подходе мы получаем 420x
ускорение