我正在寻找一种有效的方法,可以在更大的矩阵上执行子矩阵操作,而无需使用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)
答案 0 :(得分:2)
使用scipy代替图像处理操作:
答案 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]])