Combining slicing and broadcasted indexing for multi-dimensional numpy arrays

后端 未结 3 1564
别跟我提以往
别跟我提以往 2021-01-23 09:27

I have a ND numpy array (let say for instance 3x3x3) from wich I\'d like to extract a sub-array, combining slices and index arrays. For instance:

import numpy as         


        
3条回答
  •  悲&欢浪女
    2021-01-23 10:03

    The indexing subspaces of ind1 are (2,),(3,),(2,), and the resulting B is (2,3,2). This is a simple case of advanced indexing.

    ind2 is a case of (advanced) partial indexing. There are 2 indexed arrays, and 1 slice. The advanced indexing documentation states:

    If the indexing subspaces are separated (by slice objects), then the broadcasted indexing space is first, followed by the sliced subspace of x.

    In this case advanced indexing constructs a (2,2) array (from the 1st and 3rd indexes), and appends the slice dimension at the end, resulting in a (2,2,3) array.

    I explain the reasoning in more detail in https://stackoverflow.com/a/27097133/901925

    A way to fix a tuple like ind2, is to expand each slice into an array. I recently saw this done in np.insert.

    np.arange(*ind2[1].indices(3))
    

    expands : to [0,1,2]. But the replacement has to have the right shape.

    ind=list(ind2)
    ind[1]=np.arange(*ind2[1].indices(3)).reshape(1,-1,1)
    A[ind]
    

    I'm leaving off the details of determining which term is a slice, its dimension, and the relevant reshape. The goal is to reproduce i1.

    If indices were generated by something other than ix_, reshaping this slice could be more difficult. For example

    A[np.array([0,1])[None,:,None],:,np.array([0,2])[None,None,:]] # (1,2,2,3)
    A[np.array([0,1])[None,:,None],np.array([0,1,2])[:,None,None],np.array([0,2])[None,None,:]]
    # (3,2,2)
    

    The expanded slice has to be compatible with the other arrays under broadcasting.

    Swapping axes after indexing is another option. The logic, though, might be more complex. But in some cases transposing might actually be simpler:

    A[np.array([0,1])[:,None],:,np.array([0,2])[None,:]].transpose(2,0,1)
    # (3,2,2)
    A[np.array([0,1])[:,None],:,np.array([0,2])[None,:]].transpose(0,2,1)
    # (2, 3, 2)
    

提交回复
热议问题