【发布时间】:2017-11-22 02:58:35
【问题描述】:
我需要编写一个脚本,对 4 个相似的 500x500 图像的堆栈逐个像素地进行最小二乘拟合。如中所示,我需要将所有四个图像上特定像素位置的值拟合为长度为 3 的向量,对每个像素使用相同的 4x3 矩阵。
如果不对每个像素进行嵌套的 for 循环迭代,我没有办法做到这一点,所以我认为 cython 可以加快速度。我以前从未使用过 cython,但我根据文档示例编写了以下代码。
问题是,它的运行速度与纯 python 实现(约 25 秒)一样慢或更慢(约 27 秒)。
有没有人看到是什么减慢了速度?谢谢!
import numpy as np
cimport numpy as np
cimport cython
npint = np.int16
npfloat = np.float64
ctypedef np.int16_t npint_t
ctypedef np.float64_t npfloat_t
@cython.boundscheck(False)
@cython.wraparound(False)
def fourbythree(np.ndarray[npfloat_t, ndim=2] U_mat, np.ndarray[npint_t, ndim=3] G):
assert U_mat.dtype == npfloat and G.dtype == npint
cdef unsigned int z = G.shape[0]
cdef unsigned int rows = G.shape[1]
cdef unsigned int cols = G.shape[2]
cdef np.ndarray[npfloat_t, ndim= 3] a = np.empty((z - 1, rows, cols), dtype=npfloat)
cdef npfloat_t resid
cdef unsigned int rank
cdef Py_ssize_t row, col
cdef np.ndarray s
for row in range(rows):
for col in range(cols):
a[:, row, col] = np.linalg.lstsq(U_mat, G[:, row, col])[0]
return a
【问题讨论】:
-
我很快尝试使用 numba jit-compile 一个类似的函数(循环
lstsq),它的加速因子约为 7。所以肯定可以通过编译来加速它,但我不太了解 Cython,无法告诉你出了什么问题。 -
你是如何准确计时的? 230ms 对于纯 Python 实现来说似乎太快了。我看到 compiled 版本的时间大约是 20 秒...
-
@kazemakase 我使用了 ipython 的 %timeit 命令。我刚刚意识到我在测试时在一个较小的阵列(50x50 图像)上运行了这些测试,我已经用新的时间更新了帖子以获取更大的阵列。仍然得到大约相同的时间。我会看numba,那可能更简单!
标签: python numpy cython least-squares