切片 3D 的 numpy 数组。

23

请考虑以下内容:

A = np.zeros((2,3))
print(A)

[[ 0.  0.  0.]
 [ 0.  0.  0.]]
这对我来说是有意义的。我告诉numpy制作一个2x3矩阵,它就制作了一个2x3矩阵。
然而,接下来的内容:
B = np.zeros((2, 3, 4))
print(B)
给我这个:
[[[ 0.  0.  0.  0.]
  [ 0.  0.  0.  0.]
  [ 0.  0.  0.  0.]]

 [[ 0.  0.  0.  0.]
  [ 0.  0.  0.  0.]
  [ 0.  0.  0.  0.]]]

我不理解这个。我难道不是在让numpy创建一个包含4个2x3矩阵的立方体吗?我更加困惑的是,尽管数据结构看起来不正确,但切片的结果却完全符合计划:

print(B[:,:,1])

[[ 0.  0.  0.]
 [ 0.  0.  0.]]

我对这些数组的构建方式有所遗漏,但我不确定是什么。能否有人解释一下我所遗漏或不理解的内容?

非常感谢!

3个回答

27
NumPy数组会先迭代左边的轴。因此,如果B形状为(2,3,4),那么B[0]的形状为(3,4),B[1]的形状也是(3,4)。从这个意义上来说,你可以将B看作形状为(3,4)的两个数组。在B的repr中,你可以看到这两个数组的样子。
In [233]: B = np.arange(2*3*4).reshape((2,3,4))
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],       <-- first (3,4) array 
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],      <-- second (3,4) array 
        [20, 21, 22, 23]]])

你可以将B看作是通过首先迭代最后一个索引来包含四个2x3数组的。
for i in range(4):
    print(B[:,:,i])

# [[ 0  4  8]
#  [12 16 20]]
# [[ 1  5  9]
#  [13 17 21]]
# [[ 2  6 10]
#  [14 18 22]]
# [[ 3  7 11]
#  [15 19 23]]

但你也可以将 B 想象成三个 2x4 的数组:

for i in range(3):
    print(B[:,i,:])

# [[ 0  1  2  3]
#  [12 13 14 15]]
# [[ 4  5  6  7]
#  [16 17 18 19]]
# [[ 8  9 10 11]
#  [20 21 22 23]]

NumPy数组在这方面是非常灵活的。但是就Brepr而言,你看到的对应于两个(3x4)数组,因为B按照最左边的轴进行迭代。

for arr in B:
    print(arr)

# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]
# [[12 13 14 15]
#  [16 17 18 19]
#  [20 21 22 23]]

8

我希望下面的例子能够澄清你提出的第二个问题,即当你键入print(B[:,:,1])时如何获得一个2X3矩阵。

import numpy as np
B = [[[1,2,3,4],
  [5,6,7,8],
  [9,10,11,12]],

 [[13,14,15,16],
  [17,18,19,20],
  [21,22,23,24]]]

B = np.array(B)
print(B)
print()
print(B[:,:,1])

[[[ 1  2  3  4]
  [ 5  6  7  8]
  [ 9 10 11 12]]

 [[13 14 15 16]
  [17 18 19 20]
  [21 22 23 24]]]

[[ 2  6 10]
 [14 18 22]]

自从B的维度为2X3X4,这意味着就像B的repr所表示的那样,您有两个大小为3X4的矩阵。
现在在B[:,:,1]中,我们传递了:,:和1。第一个:表示我们选择了两个3X4矩阵。第二个:表示我们从这两个3X4矩阵中选择了所有行。第三个参数1表示我们只选择了这两个3X4矩阵中所有行的第二列值。因此我们得到:
[[ 2  6 10]
 [14 18 22]]

3

B是一个3D矩阵。你指定的索引(2x3x4)正是打印出来的。最外层括号有2个元素,中间括号有3个元素,最内层括号有4个元素。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接