根据 Python 中的变量将 n 维 numpy 数组转换为二维数组

transform n-dimensional numpy array to a 2D-array based on a variable in Python

我正在尝试在由(不同值的 N 参数)跨越的 N 维数组中找到最小值,并取出由(N 参数)中的 2 个围绕最小值跨越的二维数组制作等值线图的值。 我可以通过对不同情况进行硬编码来做到这一点,但最好使用应提取哪个轴的变量列表来完成 (contour_param)。

请参阅下面的代码以获得一些说明。

import numpy as np

np.random.seed(10) # seed random for reproducebility

#Example for a 3D input array (my_data)
param_sizes = [2, 3, 4]

#Generate a data_cube
my_data = np.random.normal(size=np.prod(param_sizes)).reshape(param_sizes)

#find minimum
min_pos = np.where(my_data == my_data.min())    


#what I want:
#define a parameter with the indexs of the axis to be used for the contour plot: e.i. : contour_param = [0, 1] 
               
#for contour_param = [0, 1] i would need the the 2D array:
result = my_data[:, :, min_pos[2][0]]

#for contour_param = [1, 2] i would need the the 2D array: 
result = my_data[min_pos[0][0], :, :]



#What I have tried is to convert min_pos to a list and change the entries to arrays:
contour_param = [0, 1] 
min_pos = list(np.where(my_data == my_data.min()))
min_pos[contour_param[0]] = np.arange(param_sizes[contour_param[0]])
min_pos[contour_param[1]] = np.arange(param_sizes[contour_param[1]])

result = my_data[min_pos] #This throws an error


#In an attempt to clarify - I have included a sample for a 4D array
#Example for a 4D array
param_sizes = [2, 3, 4, 3]


#Generate a data_cube
my_data = np.random.normal(size=np.prod(param_sizes)).reshape(param_sizes)

#find minimum
min_pos = np.where(my_data == my_data.min())    

                
#for contour_param = [0, 1] i would need the the 2D array:
result = my_data[:, :, min_pos[2][0], min_pos[3][0]]

#for contour_param = [1, 2] i would need the the 2D array 
result = my_data[min_pos[0][0], :, :, min_pos[3][0]]

好问题...

您可以为此使用 np.s_,因为您可以用它构建您的切片器。

例如函数:

def build_slicer(contour_param,min_pos):
    
    assert len(contur_param) + 1 == min_pos.shape[0]

    output = []  # init a emtpy output list
    
    for main_index in range(min_pos.shape[0]):
        
        if main_index in contour_param:  
            output.append(np.s_[:])
             
        else:
            output.append(np.s_[min_pos[main_index][0]])
        
    return tuple(output)

会 return:

import numpy as np
np.random.seed(10)

param_sizes = [2, 3, 4]
my_data = np.random.normal(size=np.prod(param_sizes)).reshape(param_sizes)
min_pos = np.where(my_data == my_data.min())    

contour_param = [0,2]

build_slicer(contour_param,min_pos)  
>>> (slice(None, None, None), 2, slice(None, None, None))

然后您可以使用它来切片您的数组

slice = build_slicer(contour_param,min_pos)  
my_data[slice]