如何避免双for循环?

时间:2019-05-01 15:16:29

标签: python-3.x numpy for-loop

我想使用来自其他2个矩阵的数据来计算2个矩阵的一部分(内部,外部)。它们都一样大小。下面的代码可以工作,但是在大型矩阵上速度太慢。在另一种情况下,我使用了np.fromfunction,但它不仅计算了整个矩阵,还计算了一个子集。

double for循环最快的替代方法是什么?

F = np.random.rand(100,100)
S = 10*np.random.rand(100,100) + 1

L,C = F.shape

inner = np.zeros((L,C))
outer = np.zeros((L,C))

for l in range(5, L - 5):
    for c in range(5, C - 5):
        inner[l,c] = np.mean(F[l-5 : l+5 , c-5:c])
        outer[l,c] = np.mean(F[l-5 : l+5 , c+5 : c+5+int(S[l,c])])

1 个答案:

答案 0 :(得分:0)

看来innerF上10x5平均滤波器卷积的结果。这很容易用scipy进行卷积重写,并且将尽可能快地从CPU获得。但是,由于要在矩阵的边界上保留5行和5列,因此必须截断输出innerinner2矩阵才能进行比较。

import numpy as np
from scipy.signal import convolve2d

F = np.random.rand(100,100)
S = 10*np.random.rand(100,100) + 1

L,C = F.shape

inner = np.zeros((L,C))
outer = np.zeros((L,C))

for l in range(5, L - 5):
    for c in range(5, C - 5):
        inner[l, c] = np.mean(F[l-5 : l+5 , c-5:c])
        outer[l, c] = np.mean(F[l-5 : l+5 , c+5 : c+ 5 + int(S[l, c])])

# if inner[l, c] = np.mean(F[l-5 : l+5 , c-5:c+5]),
# then you should use a 10x10 filter
avg_filter = np.ones((10, 5)) / (10*5)
inner2 = convolve2d(F, avg_filter, mode='valid')

# should be very small (1.262e-13 for me)
print((inner2[:89, :89] - inner[5:94, 5:94]).sum()) 

outer的表达式很奇怪,因为您要在表达式中加上这个int(S[l, c])偏移量。我认为您不能将其表示为矩阵计算。 因此,要替换双for循环,可以使用from itertools import product对两个可迭代对象的笛卡尔积进行迭代,如下所示:

from itertools import product

for (l, c) in product(range(5, L - 5), range(5, C - 5)):
    outer[l, c] = np.mean(F[l-5 : l+5 , c+5 : c+ 5 + int(S[l, c])])

从信号处理的角度来看,我不确定outer矩阵应该是什么。如果您告诉我们您要做什么,那么编写具有预期效果的更快代码会更容易。

相关问题