Я написал следующий код на Python. Если я использую этот код, это займет 1 минуту 20 секунд:
def calc_cy(searchX,searchY,searchZ,dx,dz,r_vector,p_true,a_factor,sim):
calc1 = np.full((len(searchX),len(searchY),len(searchZ)),np.nan)
z_t = np.abs(np.ceil(r_vector[:,2]/dz).squeeze())
for ix in searchX:
for iy in searchY:
for iz in searchZ:
dt=[]
ir = (np.floor((((ix-r_vector[:,0])**2+(iy-r_vector[:,1])**2))**0.5))
for ip in range(p_true.size):
dt.append(sim[int(iz)][int(ir[ip]),int(z_t[ip])])
dt_sim = dt-min(dt)
dt_true=p_true-min(p_true[0])
calc1[int(ix),int(iy),int(iz)]=np.linalg.norm(a_factor*(dt_sim-dt_true))
return calc1
Если я использую этот код с Cython, это займет 1 минуту 5 секунд:
код установки:
from distutils.core import setup
from Cython.Build import cythonize
import numpy
setup(ext_modules = cythonize("calc_cy.pyx"), include_dirs = [numpy.get_include()])
Код с использованием Cython:
import numpy as np
cimport numpy as np
import math
DTYPE = np.double
ctypedef np.double_t DTYPE_t
def calc_cy(np.ndarray [DTYPE_t,ndim = 3] sim,np.ndarray [DTYPE_t,ndim = 1] searchX,np.ndarray [DTYPE_t,ndim = 1] searchY,np.ndarray [DTYPE_t,ndim = 1] searchZ,np.ndarray [DTYPE_t,ndim = 2] r_vector,np.ndarray [DTYPE_t,ndim = 1] p_true,np.ndarray [DTYPE_t,ndim = 1] a_factor):
cdef np.ndarray[DTYPE_t,ndim = 3] calc1 = np.zeros((len(searchX),len(searchY),len(searchZ)),dtype = DTYPE)
cdef np.ndarray[DTYPE_t,ndim = 1] dt2 = np.zeros(len(p_true),dtype = DTYPE)
cdef np.ndarray[DTYPE_t,ndim = 1] dt_sim = np.zeros(len(dt2),dtype = DTYPE)
cdef np.ndarray[DTYPE_t,ndim = 1] dt_picks = np.zeros(len(p_true),dtype = DTYPE)
cdef int ir
cdef int k
cdef int m
for ix in range(len(searchX)):
for iy in range(len(searchY)):
for iz in range(len(searchZ)):
for ip in range(len(p_true)):
ir= int(np.floor((((searchX[ix]-r_vector[ip,0])**2+(searchY[iy]-r_vector[ip,1])**2))**0.5))
k = int(searchZ[iz])
m = int(math.fabs(math.ceil(r_vector[ip,2])))
dt2[int(ip)] = sim[k,ir,m]
dt_sim = dt2- min(dt2)
dt_true = p_true - min(p_true)
calc1[ix,iy,iz] = np.linalg.norm(a_factor*(dt_sim-dt_true))
return calc1
Как я могу улучшить свой код и сделать его более эффективным? Спасибо!