我需要写一个脚本,将做最小二乘拟合,像素为4个类似的500x500图像堆栈像素。如中所述,我需要将所有四幅图像上特定像素位置的值拟合为长度为3的向量,对每个像素使用相同的4x3矩阵。在
每一个循环我都不知道怎么做。我以前从未使用过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
您不应该需要迭代-您可以在一次调用
lstsq
中完成所有迭代。lstsq
允许第二个参数是2D,在这种情况下,结果也是2D。您的数组是3D的,但是您可以很容易地将其重塑为2D,然后将输出重新整形(并且整形基本上是免费的,它不需要复制数据):这都是非类型化的纯Python代码,因为这不是真正的索引,所以我不希望Cython能帮上忙。在
我从中得到了一个400倍的加速(尽管这其中有些是因为“一个调用”版本似乎并行运行,而Cython版本没有)。我认为加速的主要原因是重复调用Python函数的开销(考虑到它正在处理非常小的数组)。在
相关问题 更多 >
编程相关推荐