Условная нарезка многомерных массивов - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть пятимерная матрица, например ::1001*

matrix = np.random.random([3,3,3,10,2])

Я думаю об этом как о кубе 3x3x3, в каждом вокселе которого хранится матрица 10x2.

На каждом вокселе я хочу, например, получить среднее значение для поднабора элементов в первом столбце этой матрицы 10x2 на основе значений во втором столбце этой матрицы 5x2. Это вернет трехмерную матрицу - с одним числом на каждом вокселе

Я могу сделать это в цикле for, проходя через каждый воксель в терминах, но это довольно медленно.

Кажется, есть способ сделать это с использованием векторизации, который был бы намного быстрее.

Я думал, что нарезка матрицы на основе условий во втором столбце будет способом достижения этого, и тогда я мог бы иметь в виду не матрицу, а каждый отдельный воксель.

Я видел ряд примеров, делающих это с матрицами двух измерений, но я теряюсь, пытаясь сделать это на более высоких измерениях

Любой совет приветствуется

Как запросили полный код ниже:

def assign_voxels(beta_maps):
   """assign each voxel to the network it
   has the most consistent connectivity to"""
   voxel_assignment = np.empty([img_dim[0], img_dim[1], img_dim[2]])
   top_indices = np.empty([num_top_seeds, img_dim[0], img_dim[1], img_dim[2]], dtype='int')

for x in xvoxels:
    for y in yvoxels:
        for z in zvoxels:

            # the indices of nodes with greatest connectivity to the voxel:
            top_indices[:, x, y, z] = np.argsort(-betas[:, x, y, z])[:num_top_seeds]

            # connectivity values of these nodes:
            top_betas = betas[(top_indices[:, x, y, z]), x, y, z]

            # the network these nodes belong too - in same order:
            top_network_nodes = np.array([node_details[i] for i in top_indices[:, x, y, z]])

            top_combined = np.transpose(np.vstack([top_betas, top_network_nodes]))
            # empty array to be filled in below for loop
            mean_network_connectivity = np.zeros([2, num_networks])
            mean_network_connectivity[0, :] = range(1, num_networks+1)

            for network in range(1, num_networks+1):
                # betas for single network:
                individual_network = top_combined[top_combined[:, 1] == network]
                # calculate the mean connectivity value for each of these 'top' networks:
                mean_network_connectivity[1, (network-1)] = np.mean(individual_network[:, 0])

            # remove the 'none' network
            mean_network_connectivity = mean_network_connectivity[:, 0:12]

            # the network with greatest mean connectivity:
            # set voxels that show no connectivity whatsoever to 0
            if max(mean_network_connectivity[1, :]) == 0:
                # else set to the network with the createst mean connectivity
                voxel_assignment[x, y, z] = 0
            else:
                voxel_assignment[x, y, z] = 1 + np.nanargmax(mean_network_connectivity[1, :])
return voxel_assignment
...