我有一些python代码在2d和3d numpy数组上进行数值计算。代码的优化方式是它不使用任何for循环,只使用numpy操作。所有操作均在float
类型上完成。
这些是使用的numpy操作:numpy.zeros
,numpy.reshape
,numpy.where
,numpy.logical_or.reduce
,numpy.put
,numpy.add
,{{1} },numpy.subtract
,numpy.true_devide
我运行了一些测试,其开销在numpy.rint
,numpy.where
和numpy.put
操作中。
我的问题是,因为我已经优化了代码,因为它只使用了numpy操作,如果我在Cython中重写我的代码时可以期待任何显着的加速。或者可能还有其他选择?其余代码在Python中,必须保留在Python中。显着增加的是平均速度增加约20%。
EDIT1:
numpy.rint
我需要提供很多代码来使这段代码可以运行,但我希望这有助于理解它。
答案 0 :(得分:0)
您使用长行和np.put
很难理解。我认为这是等价的:
pdt = pix[:,None,:] + depthValOfU[:,None]*features[:,0]
pdt = np.rint(pdt).astype(int)
pdt = np.reshape(pdt, (2000*500, 2))
d_two = np.zeros(2000*500)
idx = np.where(np.logical_or.reduce((pdt[:,0] < 0,
pdt[:,0] > w,
pdt[:,1] < 0,
pdt[:,1] > h)))
d_two[idx] = self.const
zero_ind = np.where(d_two < 1000)
d_two[zero_ind] = im[pdt[zero_ind,0], pdt[zero_ind,1]]
根据我的经验,索引分配很快。 where
也很快。可以简化or.reduce
构造。
如果你按原样投入cython
,你将无法获得明显的加速。如果你生成-a
html,你会看到许多黄色 - 调用python和numpy。指定数组的形状和类型可能会有所帮助。但是如果没有循环,那么cython就无法改进。
键入的记忆视图可以使用&#39; native&#39;进行许多数组操作。 cython代码,但它们几乎没有numpy数组的强大功能。
另一种选择是将其重写为纯粹的迭代操作 - 在所有荣耀中都有循环。良好的矢量化numpy的反面。然后让cython将其转换为纯C.但这将是很多工作。