python - 在 python 中执行二维矩阵过滤的有效方法是什么?
问题描述
我正在尝试在 Python 中实现矩阵过滤,到目前为止,实现似乎非常缓慢且效率低下。我想知道是否有一种有效的方法来执行这种过滤。
提供一个大矩阵 A 和一个过滤矩阵 M,该函数应该返回一个“重新混合”矩阵 R,它是通过将 A 的每个元素 (i,j) 乘以 M 获得的,然后将结果叠加/插入到 R 的位置 (我,j)。请在下面找到预期执行此操作的代码。
下面的示例在我的计算机上大约需要 68 秒(!),这似乎非常低效。
如果您能推荐加速此功能的方法,我将不胜感激。提前谢谢了!
import numpy as np
import time
nx = ny = 1500
n_mix = 50
# matrix to be filtered
A = np.random.random_sample( (nx, ny) )
# filter to be applied to each point:
M = np.random.random_sample( (2*n_mix+1, 2*n_mix+1) )
# the result is stored in "remix":
remix = np.zeros_like(A)
start = time.time()
for i in range(n_mix, nx-n_mix):
for j in range(n_mix, ny-n_mix):
remix[i - n_mix:i + n_mix + 1, j - n_mix:j + n_mix + 1 ] += M * A[i,j]
print remix
duration = time.time() - start
print(round(duration))
更新
事实上,scipy 中的 ndimage 包具有完成这项工作的通用卷积函数。我在下面发布了 3 种过滤变体,其中包含受尊重的时间。最快的是 ndimage.convolution(24 秒对比其他方法的 56 和 68 秒)。但是,它似乎仍然很慢......
import numpy as np
from scipy import ndimage
import time
import sys
def remix_function(A, M):
n = (np.shape(M)[0]-1)/2
R = np.zeros_like(A)
for k in range(-n, n+1):
for l in range(-n, n+1):
# Ak = np.roll(A, -k, axis = 0)
# Akl = np.roll(Ak, -l, axis = 1)
R += np.roll(A, (-k,-l), axis = (0,1) ) * M[n-k, n-l]
return R
if __name__ == '__main__':
np.set_printoptions(precision=2)
nx = ny = 1500
n_mix = 50
nb = 2*n_mix+1
# matrix to be filtered
A = np.random.random_sample( (nx, ny) )
# filter to be applied to each point:
M = np.random.random_sample( (nb, nb) )
# the result is stored in "remix":
remix1 = np.zeros_like(A)
remix2 = np.zeros_like(A)
remix3 = np.zeros_like(A)
#------------------------------------------------------------------------------
# var 1
#------------------------------------------------------------------------------
start = time.time()
remix1 = remix_function(A, M)
duration = time.time() - start
print('time for var1 =', round(duration))
#------------------------------------------------------------------------------
# var 2
#------------------------------------------------------------------------------
start = time.time()
for i in range(n_mix, nx-n_mix):
for j in range(n_mix, ny-n_mix):
remix2[i - n_mix:i + n_mix + 1, j - n_mix:j + n_mix + 1 ] += M * A[i,j]
duration = time.time() - start
print('time for var2 =', round(duration))
#------------------------------------------------------------------------------
# var 3
#------------------------------------------------------------------------------
start = time.time()
remix3 = ndimage.convolve(A, M)
duration = time.time() - start
print('time for var3 (convolution) =', round(duration))
解决方案
我还不能评论帖子,但你的双 for 循环是问题所在。您是否尝试过定义一个函数然后使用 np.vectorize?
推荐阅读
- node.js - 使用 Benchmark.js 测试转换流 (Node.js) 期间的问题
- dart - 在 Flutter 中导航屏幕时丢失数据
- javascript - 具有基于角色的身份验证的离子侧菜单
- python - 与日期时间索引上的日期/小时的间隔比较(检查一个小时是否在两个时段之间)
- amazon-web-services - 如何从 AWS Step Function 调用外部 API?
- python - 如何显示第一列的数字并计算出现次数?
- ruby-on-rails - 多个条件不重复
- c - 如何查看 rpl-ofc.c 中的 printf 语句?
- javascript - 如何根据类别排序数组?
- python - Python:使用向后循环从文本文件中查找部分