【发布时间】:2021-02-03 15:39:07
【问题描述】:
给定一个 5D 数组,目标是计算提取的两个数组之间的差异。为简单起见,假设测量第二个位置的差异,可以表示为bt 和lf。这两个数组的值可以提取如下:
arr[ep, bt, mt, bd, :] - arr[ep, lf, mt, bd, :]
请注意,在上面,两个数组的第一个 (ep)、第三个 (mt) 和第四个 (bd) 轴的索引相同,只有第二个位置索引轴不同(bt 和 lf)。
基于这个需求,提出如下代码,并打包在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, mt, bd, :] = arr[ep, bt, mt, bd, :] - \
arr[ep, lf, mt, bd, :]
return store_cval
store_cval = nested_for_loop()
但是,如果可能的话,我想让代码更加紧凑和高效。
我能想到的一种方法是利用joblib parallel模块,可以如下实现,如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 方式。
【问题讨论】:
-
为什么只对最后一个维度进行切片?
arr[:,bt,:,:,:] and arr[:,lf,:,:,:]甚至arr[:,bt,...] and arr[:,lf,...]? -
假设最后一个维度的形状为 2 并且每个维度的值都为
[3,4]和[1,1]。所以它们之间的差异是[2,3]。这对你有意义吗@hpaulj?
标签: python performance numpy coding-efficiency