Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何优化多维numpy阵列计算?_Python_Performance_Numpy_Coding Efficiency - Fatal编程技术网

Python 如何优化多维numpy阵列计算?

Python 如何优化多维numpy阵列计算?,python,performance,numpy,coding-efficiency,Python,Performance,Numpy,Coding Efficiency,给定一个5D阵列,目标是计算提取的两个阵列之间的差异。为简单起见,假设在第二个位置测量差异,可以表示为bt和lf。这两个数组中的值可以提取如下: arr[ep, bt, mt, bd, :] - arr[ep, lf, mt, bd, :] 注意,在上面,第一(ep)、第三(mt)和第四(bd)轴的索引对于这两个阵列是相同的,只有第二轴的位置索引不同(bt和lf) 基于此要求,提出了以下代码,并将其打包在函数嵌套的\u for_循环下: import numpy as np from jobl

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

arr[ep, bt, mt, bd, :] - arr[ep, lf, mt, bd, :]
注意,在上面,第一(
ep
)、第三(
mt
)和第四(
bd
)轴的索引对于这两个阵列是相同的,只有第二轴的位置索引不同(
bt
lf

基于此要求,提出了以下代码,并将其打包在函数
嵌套的\u for_循环
下:

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, mt, bd, :] = arr[ep, bt, mt, bd, :] - \
                                                     arr[ep, lf, mt, bd, :]
    return store_cval


store_cval = nested_for_loop()
但是,如果可能的话,我想使代码更加紧凑和高效

我能想到的一种方法是利用
joblibparallel
模块,它可以实现如下所示的功能
multi_prop

def multi_prop(my_arr, ep):
    temp_ = np.full([10, my_shape[2], my_shape[3], my_shape[4]],
                    np.nan)
    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])):
                temp_[idx, mt, bd, :] = my_arr[ep, bt, mt, bd, :] - my_arr[ep, lf, mt, bd, :]
                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的方法。

您根本不需要任何循环。想象一下这对奇特的指数:

bt, lf = np.tril_indices (5, -1)
你在找什么

store_cval = arr[:, bt] - arr[:, lf]
请记住,
store_cval[ep,idx,mt,bd,:]=arr[ep,bt,mt,bd,:]-arr[ep,lf,mt,bd,:]
是上一个索引上的隐式循环。它们都是环,你不需要在引擎盖上有任何环

一个更普遍的解决方案:

def diffs(arr, axis):
    a, b = np.tril_indices(arr.shape[axis], -1)
    ind1 = [slice(None) for _ in range(arr.ndim)]
    ind2 = ind1.copy()
    ind1[axis] = a
    ind2[axis] = b
    return arr[tuple(ind1)] - arr[tuple(ind2)]

为什么只为最后一个维度创建一个切片
arr[:,bt,:,:,:,:,:]和arr[:,lf,:,:]
或者甚至
arr[:,bt,…]和arr[:,lf,…]
?假设最后一个维度的形状为2和,并且每个维度都具有值
[3,4]
[1,1]
。因此,它们之间的区别是
[2,3]
。这对你有意义吗@hpaulj?嗨@Mad,谢谢你的详细解释。由于某种原因,我无法重现上述结果。例如,
轴的值是多少。此外,我的编译器在
ind1=[slice(None)for uu.in range arr.ndim]
行上提供了预期的警告
End-of-statement
。最后,你是说
tril
成为
np.tril\u索引
?@balandongiv。对不起,我打错了。现在修好了。在本例中,您希望沿第二个轴使用组合,因此
axis=1