numpy优化代码可以通过在Cython中重写来获得显着的速度提升吗?

时间:2018-02-06 14:10:51

标签: python-2.7 performance numpy cython

我有一些python代码在2d和3d numpy数组上进行数值计算。代码的优化方式是它不使用任何for循环,只使用numpy操作。所有操作均在float类型上完成。

这些是使用的numpy操作:numpy.zerosnumpy.reshapenumpy.wherenumpy.logical_or.reducenumpy.putnumpy.add,{{1} },numpy.subtractnumpy.true_devide

我运行了一些测试,其开销在numpy.rintnumpy.wherenumpy.put操作中。

我的问题是,因为我已经优化了代码,因为它只使用了numpy操作,如果我在Cython中重写我的代码时可以期待任何显着的加速。或者可能还有其他选择?其余代码在Python中,必须保留在Python中。显着增加的是平均速度增加约20%。

EDIT1:

numpy.rint

我需要提供很多代码来使这段代码可以运行,但我希望这有助于理解它。

1 个答案:

答案 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.但这将是很多工作。