我想使用来自其他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])])
答案 0 :(得分:0)
看来inner
是F
上10x5平均滤波器卷积的结果。这很容易用scipy
进行卷积重写,并且将尽可能快地从CPU获得。但是,由于要在矩阵的边界上保留5行和5列,因此必须截断输出inner
和inner2
矩阵才能进行比较。
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
矩阵应该是什么。如果您告诉我们您要做什么,那么编写具有预期效果的更快代码会更容易。