概括NumPy数组中的切片操作

发布于 2021-01-29 19:36:02

该问题基于以下较早的问题:

给定一个数组:

In [122]: arr = np.array([[1, 3, 7], [4, 9, 8]]); arr
Out[122]:
array([[1, 3, 7],
       [4, 9, 8]])

并给出其索引:

In [127]: np.indices(arr.shape)
Out[127]:
array([[[0, 0, 0],
        [1, 1, 1]],

       [[0, 1, 2],
        [0, 1, 2]]])

如何将它们整齐地堆叠在一起以形成新的2D​​阵列?这就是我想要的:

array([[0, 0, 1],
       [0, 1, 3],
       [0, 2, 7],
       [1, 0, 4],
       [1, 1, 9],
       [1, 2, 8]])

)Divakar的这种解决方案是我目前用于2D阵列的解决方案:

def indices_merged_arr(arr):
    m,n = arr.shape
    I,J = np.ogrid[:m,:n]
    out = np.empty((m,n,3), dtype=arr.dtype)
    out[...,0] = I
    out[...,1] = J
    out[...,2] = arr
    out.shape = (-1,3)
    return out

现在,如果要传递3D数组,则需要修改此函数:

def indices_merged_arr(arr):
    m,n,k = arr.shape   # here
    I,J,K = np.ogrid[:m,:n,:k]   # here
    out = np.empty((m,n,k,4), dtype=arr.dtype)   # here
    out[...,0] = I
    out[...,1] = J
    out[...,2] = K     # here
    out[...,3] = arr
    out.shape = (-1,4)   # here
    return out

但是此功能现在仅适用于3D阵列-我无法将2D阵列传递给它。

我是否可以通过某种方式将其推广到任何维度?这是我的尝试:

def indices_merged_arr_general(arr):
    tup = arr.shape   
    idx = np.ogrid[????]   # not sure what to do here....
    out = np.empty(tup + (len(tup) + 1, ), dtype=arr.dtype) 
    for i, j in enumerate(idx):
        out[...,i] = j
    out[...,len(tup) - 1] = arr
    out.shape = (-1, len(tup)
    return out

我在这条线上遇到麻烦:

idx = np.ogrid[????]

我该如何工作?

关注者
0
被浏览
65
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    这是处理通用ndarrays的扩展-

    def indices_merged_arr_generic(arr, arr_pos="last"):
        n = arr.ndim
        grid = np.ogrid[tuple(map(slice, arr.shape))]
        out = np.empty(arr.shape + (n+1,), dtype=np.result_type(arr.dtype, int))
    
        if arr_pos=="first":
            offset = 1
        elif arr_pos=="last":
            offset = 0
        else:
            raise Exception("Invalid arr_pos")
    
        for i in range(n):
            out[...,i+offset] = grid[i]
        out[...,-1+offset] = arr
        out.shape = (-1,n+1)
    
        return out
    

    样品运行

    2D外壳:

    In [252]: arr
    Out[252]: 
    array([[37, 32, 73],
           [95, 80, 97]])
    
    In [253]: indices_merged_arr_generic(arr)
    Out[253]: 
    array([[ 0,  0, 37],
           [ 0,  1, 32],
           [ 0,  2, 73],
           [ 1,  0, 95],
           [ 1,  1, 80],
           [ 1,  2, 97]])
    
    In [254]: indices_merged_arr_generic(arr, arr_pos='first')
    Out[254]: 
    array([[37,  0,  0],
           [32,  0,  1],
           [73,  0,  2],
           [95,  1,  0],
           [80,  1,  1],
           [97,  1,  2]])
    

    3D外壳:

    In [226]: arr
    Out[226]: 
    array([[[35, 45, 33],
            [48, 38, 20],
            [69, 31, 90]],
    
           [[73, 65, 73],
            [27, 51, 45],
            [89, 50, 74]]])
    
    In [227]: indices_merged_arr_generic(arr)
    Out[227]: 
    array([[ 0,  0,  0, 35],
           [ 0,  0,  1, 45],
           [ 0,  0,  2, 33],
           [ 0,  1,  0, 48],
           [ 0,  1,  1, 38],
           [ 0,  1,  2, 20],
           [ 0,  2,  0, 69],
           [ 0,  2,  1, 31],
           [ 0,  2,  2, 90],
           [ 1,  0,  0, 73],
           [ 1,  0,  1, 65],
           [ 1,  0,  2, 73],
           [ 1,  1,  0, 27],
           [ 1,  1,  1, 51],
           [ 1,  1,  2, 45],
           [ 1,  2,  0, 89],
           [ 1,  2,  1, 50],
           [ 1,  2,  2, 74]])
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看