Numpy子矩阵操作

时间:2013-08-15 21:15:48

标签: python numpy submatrix

我正在寻找一种有效的方法,可以在更大的矩阵上执行子矩阵操作,而无需使用for循环。

我正在进行操作(对于3x3窗口):

newMatrix = numpy.zeros([numRows, numCols])
for i in range(1, numRows-1):
    for j in range(1, numCols-1):
        sub = matrix[i-1:i+2, j-1:j+2]
        newMatrix[i][j] = ... #do things with sub matrix

这比使用numpy矩阵的正常操作要慢得多。是否有任何不足以解决这个问题,还是希望得到太多?

编辑: 具体例子

xWeight = numpy.array([[-1./8, 0, 1./8], [-2./8, 0, 2./8], [-1./8, 0, 1./8]])
yWeight = numpy.array([[1./8, 2./8, 1./8], [0, 0, 0], [-1./8, -2./8, -1./8]])

内圈:

        dz_dx = numpy.sum(xWeight * sub)
        dz_dy = numpy.sum(yWeight * sub)

4 个答案:

答案 0 :(得分:2)

使用scipy代替图像处理操作:

http://scipy-lectures.github.io/advanced/image_processing/

答案 1 :(得分:2)

我在numpy.lib.stride_tricks中找到了一个解决方案

from numpy.lib.stride_tricks import as_strided

在方法中:

    expansion = stride.as_strided(matrix, shape = (numRows-2, numCols-2, 3, 3), strides = matrix.strides * 2)
    xWeight = numpy.array([[-1./8, 0, 1./8], [-2./8, 0, 2./8], [-1./8, 0, 1./8]])
    yWeight = numpy.array([[1./8, 2./8, 1./8], [0, 0, 0], [-1./8, -2./8, -1./8]])

    dx = xWeight * expansion
    dy = yWeight * expansion

    dx = numpy.sum(numpy.sum(dx, axis=3), axis=2)
    dy = numpy.sum(numpy.sum(dy, axis=3), axis=2)

可能有一个更好的解决方案,但这对我所追求的目标来说足够简单和通用。这在3.41秒内通过1600x1200矩阵,而使用for循环则通过188.47秒。

(如果有的话,请随意提供更好的解决方案)

答案 2 :(得分:2)

在我看来,你试图做一个简单的卷积?

def do(m):
    rows, cols = m.shape
    newMatrix = np.zeros_like(m)
    for i in range(1, rows-1):
        for j in range(1, cols-1):
            sub = matrix[i-1:i+2, j-1:j+2]
            newMatrix[i][j] = numpy.sum(xWeight * sub)
    return newMatrix[1:-1, 1:-1]
>>> res1 = do(matrix)
>>> res2 = scipy.signal.convolve2d(matrix, xWeight)[2:-2,2:-2]
>>> np.allclose(np.abs(res1), np.abs(res2))
True

没有详细说明这个标志,但这应该会让你走上正轨。

答案 3 :(得分:0)

您似乎可以使用np.ix_,请参阅此示例from the documentation

a = np.arange(10).reshape(2, 5)
#array([[0, 1, 2, 3, 4],
#       [5, 6, 7, 8, 9]])

ixgrid = np.ix_([0,1], [2,4])

a[ixgrid]
#array([[2, 4],
#       [7, 9]])