如何优化多维numpy数组计算?

问题描述

给定一个 5D 数组,目标是计算提取的两个数组之间的差异。为简单起见,假设测量第二个位置的差异,可以表示为 btlf。可以从这两个数组中提取值,如下所示:

arr[ep,bt,mt,bd,:] - arr[ep,lf,:]

请注意,在上面,两个数组的第一个 (ep)、第三个 (mt) 和第四个 (bd) 轴的索引是相同的,其中只有第二个轴的位置索引不同(btlf)。

基于这个需求,提出如下代码,并打包在函数nested_for_loop下:

import numpy as np
from joblib import Parallel,delayed
np.random.seed(0)

ub_lb_pair = np.tril_indices (5,-1)

arr = np.random.randn(3,5,4,3,2)
my_shape = arr.shape

def nested_for_loop():
    store_cval = np.full([my_shape[0],10,my_shape[2],my_shape[3],my_shape[4]],np.nan)  # preallocate
    for ep in range(0,my_shape[0]):
        for mt in range(0,my_shape[2]):
            for bd in range(0,my_shape[3]):
                for idx,(bt,lf) in enumerate(zip(ub_lb_pair[0],ub_lb_pair[1])):
                    store_cval[ep,idx,:] = arr[ep,:] - \
                                                     arr[ep,:]
    return store_cval


store_cval = nested_for_loop()

但是,如果可能的话,我想让代码更加紧凑和高效。

我能想到的一种方法是利用 joblib parallel 模块,可以如下实现,如函数 multi_prop 下所示。

def multi_prop(my_arr,ep):
    temp_ = np.full([10,np.nan)
    for mt in range(0,my_shape[2]):
        for bd in range(0,my_shape[3]):
            for idx,ub_lb_pair[1])):
                temp_[idx,:] = my_arr[ep,:] - my_arr[ep,:]
                x = 1
    return  temp_

dist_abs = Parallel(n_jobs=-1)(delayed(multi_prop)(arr,ep) for ep in range(0,my_shape[0]))

dist_abs = np.array(dist_abs)
bb = np.array_equal(store_cval,dist_abs)

但是,我想知道这是否是实现相同目标的更numpythonic的方式。

解决方法

您根本不需要任何循环。想象一下这对花哨的索引:

// bootstrap the DOM 
$document = new DOMDocument();
$document->load($xmlFile);

// fetch nodes using an xpath expression 
$xpath = new DOMXpath($document);
$products = $xpath->evaluate('//Product[onlineShopVisibility="notVisibleOnline"]');

// iterate nodes
foreach ($products as $product) {
    // remove node
    $product->parentNode->removeChild($product);
}

$document->save($xmlFile);

您正在寻找

bt,lf = np.tril_indices (5,-1)

请记住,store_cval = arr[:,bt] - arr[:,lf] 是对最后一个索引的隐式循环。它们都是循环,你不需要在引擎盖上使用它们中的任何一个。

更通用的解决方案:

store_cval[ep,idx,mt,bd,:] = arr[ep,bt,:] - arr[ep,lf,:]