【问题标题】:Slicing/Indexing with multidimensional arrays using Numpy使用 Numpy 对多维数组进行切片/索引
【发布时间】:2018-11-07 11:29:21
【问题描述】:

我创建了 3 个 4x4 数组(矩阵):arr=np.linspace(1,48,48).reshape(3,4,4)

矩阵如下所示:`

[[[ 1.  2.  3.  4.]
  [ 5.  6.  7.  8.]
  [ 9. 10. 11. 12.]
  [13. 14. 15. 16.]]

 [[17. 18. 19. 20.]
  [21. 22. 23. 24.]
  [25. 26. 27. 28.]
  [29. 30. 31. 32.]]

 [[33. 34. 35. 36.]
  [37. 38. 39. 40.]
  [41. 42. 43. 44.]
  [45. 46. 47. 48.]]]`

我想执行索引/拼接以获得某些输出 例如:

[[36. 35.] [40. 39.] [44. 43.] [48. 47.]]

[[13. 9. 5. 1.] [29. 25. 21. 17.] [45. 41. 37. 33.]]


[[25. 26. 27. 28.], [29. 30. 31. 32.], [33. 34. 35. 36.], [37. 38. 39. 40.]]

4*. [[1. 4.] [45. 48.]]

我正在努力解决如何处理它。在使用特定矩阵时,我尝试访问该矩阵,然后从那里拼接/索引。例如,输出 [[36. 35.] [40. 39.] [44. 43.] [48. 47.]] 位于第三个矩阵中。我像这样访问矩阵matrix3 = arr[array([2])]

现在我只处理第三个矩阵中的行和列,并且发现很难正确切片。 matrix3[::-1,::-1] 是否应该同时反转列和行?如果是,那么这是处理它的最佳方法吗?相反,我应该使用 reshape 吗?你应该在所有 3 个 4x4 数组上使用 reshape 还是访问要使用的矩阵然后 reshape?

编辑:添加 4.

【问题讨论】:

    标签: python arrays numpy indexing slice


    【解决方案1】:

    逐步提取您的第一个结果:

    In [53]: arr[2,:,:]            # the desired plane
    Out[53]: 
    array([[33, 34, 35, 36],
           [37, 38, 39, 40],
           [41, 42, 43, 44],
           [45, 46, 47, 48]])
    In [54]: arr[2,:,2:]          # the desired columns
    Out[54]: 
    array([[35, 36],
           [39, 40],
           [43, 44],
           [47, 48]])
    In [55]: arr[2,:,:1:-1]        # the reversed order
    Out[55]: 
    array([[36, 35],
           [40, 39],
           [44, 43],
           [48, 47]])
    

    或者如果它更容易,作为一个单独的步骤反转:

    In [56]: arr[2,:,2:][:,::-1]
    Out[56]: 
    array([[36, 35],
           [40, 39],
           [44, 43],
           [48, 47]])
    

    第二次

    In [57]: arr[:,:,0]          # select column
    Out[57]: 
    array([[ 1,  5,  9, 13],
           [17, 21, 25, 29],
           [33, 37, 41, 45]])
    In [58]: arr[:,::-1,0]        # reverse
    Out[58]: 
    array([[13,  9,  5,  1],
           [29, 25, 21, 17],
           [45, 41, 37, 33]])
    In [59]: arr[:,::-1,0].T      # transpose
    Out[59]: 
    array([[13, 29, 45],
           [ 9, 25, 41],
           [ 5, 21, 37],
           [ 1, 17, 33]])
    

    第三

    这有点棘手。我们想要一架飞机的最后两行,另一架飞机的前两行。为此,我们需要一对将广播到正确形状的索引,将 1[2,3] 等配对。

    In [61]: arr[[[1],[2]],[[2,3],[0,1]],:]
    Out[61]: 
    array([[[25, 26, 27, 28],
            [29, 30, 31, 32]],
    
           [[33, 34, 35, 36],
            [37, 38, 39, 40]]])
    

    这是一个 3d 矩阵;将其减少到 2d 的一种方法是连接:

    In [63]: np.concatenate(arr[[[1],[2]],[[2,3],[0,1]],:],axis=0)
    Out[63]: 
    array([[25, 26, 27, 28],
           [29, 30, 31, 32],
           [33, 34, 35, 36],
           [37, 38, 39, 40]])
    

    reshape 也同样有效:

    In [65]: arr[[[1],[2]],[[2,3],[0,1]],:].reshape(4,4)
    Out[65]: 
    array([[25, 26, 27, 28],
           [29, 30, 31, 32],
           [33, 34, 35, 36],
           [37, 38, 39, 40]])
    

    还有arr.reshape(3,2,2,4)[[1,2],[1,0],:].reshape(4,4)


    您可以将这些索引表达式编写为带有切片的元组,例如:

    In [66]: idx = (2, slice(None), slice(None,1,-1))
    In [67]: arr[idx]
    Out[67]: 
    array([[36, 35],
           [40, 39],
           [44, 43],
           [48, 47]])
    

    因此,一般来说,常用工具包括索引(使用切片、标量和列表)、反转(-1 步)、转置(或交换轴)和整形。你不能只用其中一个来做所有事情。

    【讨论】:

    • 谢谢。将切片分解为步骤确实有助于澄清哪些位置会影响矩阵。
    【解决方案2】:

    您在切片方面走在了正确的轨道上!对于您想要的输出尝试:

    arr[2,:,:1:-1]
    np.vstack((arr[i, ::-1, 0] for i in range(3)))
    np.vstack((arr[1, 2:, :], arr[2, :2, :]))
    

    输出:

    array([[36., 35.],
       [40., 39.],
       [44., 43.],
       [48., 47.]])
    
    array([[13.,  9.,  5.,  1.],
       [29., 25., 21., 17.],
       [45., 41., 37., 33.]])
    
    array([[25., 26., 27., 28.],
       [29., 30., 31., 32.],
       [33., 34., 35., 36.],
       [37., 38., 39., 40.]])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-25
      • 2020-01-20
      • 1970-01-01
      • 1970-01-01
      • 2015-10-23
      • 2014-04-04
      • 2022-01-24
      相关资源
      最近更新 更多