在Cython中用NumPy函数进行阵元的最小二乘拟合

2024-09-30 02:30:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要写一个脚本,将做最小二乘拟合,像素为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

Tags: npcol像素cythonintrowndarrayshape
1条回答
网友
1楼 · 发布于 2024-09-30 02:30:24

您不应该需要迭代-您可以在一次调用lstsq中完成所有迭代。lstsq允许第二个参数是2D,在这种情况下,结果也是2D。您的数组是3D的,但是您可以很容易地将其重塑为2D,然后将输出重新整形(并且整形基本上是免费的,它不需要复制数据):

a = np.linalg.lstsq(U_mat, G.reshape((G.shape[0],-1)))[0]
a = a.reshape((a.shape[0],G.shape[1],G.shape[2]))

这都是非类型化的纯Python代码,因为这不是真正的索引,所以我不希望Cython能帮上忙。在

我从中得到了一个400倍的加速(尽管这其中有些是因为“一个调用”版本似乎并行运行,而Cython版本没有)。我认为加速的主要原因是重复调用Python函数的开销(考虑到它正在处理非常小的数组)。在

相关问题 更多 >

    热门问题