【问题标题】:How does slicing in three dimensional numpy array work?在三维 numpy 数组中切片如何工作?
【发布时间】:2021-08-26 11:48:30
【问题描述】:
import numpy as np
arr = np.array([[[1,2,3], [4,5,6]], [[7,8,9],[10,11,12]]])
print(arr[0:2, : , 2] 

我知道选择了元素 3、6、9 和 12,但无法确定输出是否为 打印为一维数组或二维数组或更多。 它是如何工作的?

输出:

【问题讨论】:

  • 您可以查看尺寸arr[0:2, : , 2].ndim或形状arr[0:2, : , 2].shape
  • 嗨 Sandeep,花时间在advance indexing 上阅读这份官方文档是值得的。这应该让您清楚为什么您的输出看起来像这样。
  • 简短回答:在索引 numpy 后自动删除单个维度(= 长度为一的轴)。

标签: python python-3.x numpy numpy-slicing


【解决方案1】:
arr = np.array([[[1,2,3], [4,5,6]], [[7,8,9],[10,11,12]]])

# array([[[ 1,  2,  3],
#         [ 4,  5,  6]],

#        [[ 7,  8,  9],
#         [10, 11, 12]]])

arr.shape # ------> (2,2,3)
# Think of them as axis
# lets create the first 2 axis of (`2`, ...)

#         |(1)
#         |
#         |
#         |         
#         |---------(0)


# now lets create second 2 axis of (2, `2`, ..)

#            (1,1)
#         |
#         |---(1,0)
#         |
#         |
#         |
#         |         |(0,1)
#         |---------|---(0,0)

# now lets create the last 3 axis of (2, 2, `3`)

#           /``(1,1,0) = 10
#          |-- (1,1,1) = 11
#         | \__(1,1,2) = 12
#         |
#         |  /``(1,0,0) = 7
#         |--|--(1,0,1) = 8
#         |  \__(1,0,2) = 9
#         |
#         |
#         |         /``(0,1,0) = 4
#         |         |--(0,1,1) = 5
#         |         \__(0,1,2) = 6
#         |         |
#         |         |
#         |---------|---/``(0,0,0) = 1
#                       |--(0,0,1) = 2
#                       \__(0,0,2) = 3

# now suppose you ask
arr[0, :, :] # give me the first axis alon with all it's component

#         |
#         |         /``(0,1,0) = 4
#         |         |--(0,1,1) = 5
#         |         \__(0,1,2) = 6
#         |         |
#         |         |
#         |---------|---/``(0,0,0) = 1
#                       |--(0,0,1) = 2
#                       \__(0,0,2) = 3

# So it will print 

# array([[1, 2, 3],
#        [4, 5, 6]])

arr[:, 0, :] # you ask take all the first axis 1ut give me only the first axis of the first axis and all its components

#           
#         
#         
#         
#         |  /``(1,0,0) = 7
#         |--|--(1,0,1) = 8
#         |  \__(1,0,2) = 9
#         |
#         |
#         |         
#         |         
#         |         
#         |         
#         |         
#         |---------|---/``(0,0,0) = 1
#                       |--(0,0,1) = 2
#                       \__(0,0,2) = 3

# so you get the output

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

# like wise you ask
print(arr[0:2, : , 2])
# so you are saying give (0,1) first axis, all of its children and only 3rd (index starts at 0 so 2 means 3) children
# 0:2 means 0 to 2 `excluding` 2; 0:5 means 0,1,2,3,4

#           
#          |
#         | \__(1,1,2) = 12
#         |
#         |  
#         |--
#         |  \__(1,0,2) = 9
#         |
#         |
#         |        
#         |         
#         |         \__(0,1,2) = 6
#         |         |
#         |         |
#         |---------|---/
#                       |
#                       \__(0,0,2) = 3

# so you get

# array([[ 3,  6],
#        [ 9, 12]])

【讨论】:

    【解决方案2】:

    进入

    给定数组:

        arr = np.array([[[1,2,3], [4,5,6]], [[7,8,9],[10,11,12]]])
    

    arr.shape 给出的 arr 的形状是(2,2,3)

    这基本上意味着如果我们从外部开始(并忽略第一个方括号),我们在该范围内有 2 个数组。如果我们输入其中之一,我们可以计算 2 个数组,如果我们输入其中一个,我们会找到 3 个元素。我认为拥有这种观点对于理解以下内容非常有帮助。

    指定arr[1,1,2]选择最外层范围内的第二个数组(索引1),then选择后面范围内的第二个数组,then选择第三个元素.输出是一个数字:

        12
    

    指定arr[:,1,2] 首先同时选择最外层范围内的所有数组,然后为每个选择第二个数组(索引 1)。当我们然后进入下一个作用域时,我们挑选出第三个元素。这会输出两个数字:

        array([ 6, 12])
    

    指定 arr[:, : , 2] 输出 4 个数字,因为 1. 在第一个范围内,我们选择了所有数组 (2) 2. 在下一个范围内,我们选择了所有数组(第一个数组各 2 个)

        array([[ 3,  6],
               [ 9, 12]])
    

    出来

    本能地,它们之所以显示为 2x2 数组,可以看作是从最低范围后退。元素被括在方括号中,因为它们共享一个范围。 3 和 6 将在一个数组中,而 9 和 12 将在另一个数组中。

    【讨论】:

      【解决方案3】:

      您可以使用reshape(),如下所示:

      import numpy as np
      arr = np.array([[[1,2,3], [4,5,6]], [[7,8,9],[10,11,12]]])
      
      first = arr[0:2, : , 2]
      print(first)
      print(first.shape)
      
      second = first.reshape(1,-1)
      print(second)
      print(second.shape)
      

      输出:

      [[ 3  6]
       [ 9 12]]
      
      (2, 2)
      
      [[ 3  6  9 12]]
      
      (1, 4)
      

      【讨论】:

      • 是的,但我想了解它是如何工作的,并知道输出。感谢您的回复。
      • @Sandeep,我编辑了答案,你可以使用shape 来获取尺寸并使用 reshape 来改变尺寸,就像上面一样,这对你有帮助吗?
      【解决方案4】:

      要检查数组的形状,只需运行 .shape 方法:

      import numpy as np
      arr = np.array([[[1,2,3], [4,5,6]], [[7,8,9],[10,11,12]]])
      print(arr[0:2, : , 2].shape)
      

      输出:(2, 2)

      所以你有一个 2 x 2 数组。

      希望对你有帮助!

      【讨论】:

        【解决方案5】:

        Numpy N 维数组/列表 基本上在使用普通列表切片时

        普通列表

        start,end=0,5
        l=[1,2,3,4,5]
        print(l[start:end])
        
        [1,2,3,4,5]
        

        Numpy 数组 ([List[list[list..]]])

        所以这里当我们引用给定的 numpy 数组时 arr=[[[1,2,3], [4,5,6]], [[7,8,9],[10,11,12]]]

        Level 0拼接基础元素

        arr[0:]  [[[1,2,3], [4,5,6]], [[7,8,9],[10,11,12]]]
        arr[1:]  [[[7,8,9],[10,11,12]]
        

        Level 1 拼接 base Elems

        child
        arr[0:,1:] [[[4,5,6]],[[10,11,12]]]
        

        Level 2 拼接 child Elems

        subchilds
        arr[0:,1:,1:] [[[5,6]],[[11,12]]]
        

        【讨论】:

          【解决方案6】:

          索引/切片 3d 数组实际上与在 1d、2d 或 20d 上执行相同操作没有什么不同。

          In [580]: arr
          Out[580]: 
          array([[[ 1,  2,  3],
                  [ 4,  5,  6]],
          
                 [[ 7,  8,  9],
                  [10, 11, 12]]])
          In [581]: arr[:,:,2]
          Out[581]: 
          array([[ 3,  6],
                 [ 9, 12]])
          

          对于 (2,2,3) 形状,使用0:2 切片与: 相同,即整个维度。因此,您的示例仅选择沿最后一个轴的“2”子数组。使用标量进行索引会减少该维度,因此 (2,2,3) => (2,2)。

          查看结果值在原始数据中的位置 - 最右侧的列,但拆分为 2 个平面。 2 个平面中的 2 个高列导致一个 (2,2) 数组。

          numpy 具有灵活的多维数组布局和相应的索引系统。这意味着arr[:,1,:]arr[1,:,:] 甚至arr[1,:,2] 都以相同的方式工作,尽管结果不同。但底层机制基本相同。

          In [582]: arr[1,:,:]
          Out[582]: 
          array([[ 7,  8,  9],
                 [10, 11, 12]])
          In [583]: arr[1,:,2]
          Out[583]: array([ 9, 12])
          In [585]: arr[:,1,2]
          Out[585]: array([ 6, 12])
          

          【讨论】:

            猜你喜欢
            • 2019-08-30
            • 1970-01-01
            • 2015-01-29
            • 2021-11-23
            • 1970-01-01
            • 2012-10-26
            • 2022-01-19
            • 2017-04-01
            相关资源
            最近更新 更多