如何避免使用numpy for-loops?

use*_*tar 4 python numpy

我已经编写了下面这段代码,它完全符合我的要求,但速度太慢了.我确信有一种方法可以让它更快,但我似乎无法找到它应该如何完成.代码的第一部分只是为了显示哪种形状.

测量(VV1HH1)
预计算值,VV模拟和HH模拟的两个图像,它们都依赖于3个参数(预先计算(101, 31, 11)值)
索引2只是将VVHH图像放在同一个ndarray中,而不是制作两个3darrays

VV1 = numpy.ndarray((54, 43)).flatten()
HH1 = numpy.ndarray((54, 43)).flatten()
precomp = numpy.ndarray((101, 31, 11, 2))
Run Code Online (Sandbox Code Playgroud)

我们让三个参数中的两个变化

comp = numpy.zeros((len(parameter1), len(parameter2)))

for i,(vv,hh) in enumerate(zip(VV1,HH1)):
    comp0 = numpy.zeros((len(parameter1),len(parameter2)))
    for j in range(len(parameter1)):
        for jj in range(len(parameter2)):
            comp0[j,jj] = numpy.min((vv-precomp[j,jj,:,0])**2+(hh-precomp[j,jj,:,1])**2)
    comp+=comp0
Run Code Online (Sandbox Code Playgroud)

我知道我应该做的显而易见的事情是摆脱尽可能多的for循环,但我不知道如何numpy.min在处理更多维度时使行为正常.

第二件事(不太重要,如果它可以得到矢量化,但仍然很有趣)我注意到它主要占用CPU时间,而不是RAM,但我已经搜索了很长时间,但我找不到一种方法来写"parfor "在matlab中代替"for",(@parallel如果我只是将for循环放在一个单独的方法中,是否可以制作一个装饰器?)

编辑:回答Janne Karila:是的,肯定会改善它,

for (vv,hh) in zip(VV1,HH1):
    comp+= numpy.min((vv-precomp[...,0])**2+(hh-precomp[...,1])**2, axis=2)
Run Code Online (Sandbox Code Playgroud)

肯定是快得多,但有没有可能删除外部for循环?有没有办法使for-loop并行,有@parallel什么东西?

Jan*_*ila 5

这可以取代内环,jjj

comp0 = numpy.min((vv-precomp[...,0])**2+(hh-precomp[...,1])**2, axis=2)
Run Code Online (Sandbox Code Playgroud)

这可能是整个循环的替代品,尽管所有这些索引都让我有点兴奋.(这会创建一个大的中间数组)

comp = numpy.sum(
        numpy.min((VV1.reshape(-1,1,1,1) - precomp[numpy.newaxis,...,0])**2
                 +(HH1.reshape(-1,1,1,1) - precomp[numpy.newaxis,...,1])**2, 
                 axis=2),
        axis=0)
Run Code Online (Sandbox Code Playgroud)