打印NumPy数组时的轴顺序

时间:2017-09-06 13:42:01

标签: python arrays python-3.x numpy multidimensional-array

我在NumPy中使用3d数组,我必须经常查看数组元素。假设我有a a.shape (10,5,3)的数组(10,5)。我正在使用这是3个形状print(a) 平面的感觉,我想这样看。

例如,如果我

[[[ 0  0  0]
  [ 0  0  0]
  [ 0  0  0]
  [ 0  0  0]
  [ 0  0  0]]

 [[ 0  0  0]
  [ 0 22  0]
  [11 22 33]
  [ 0  0  0]
  [ 0  0  0]]

 [[ 0  0  0]
  [11 22 33]
  [ 0  0  0]
  [11 22 33]
  [ 0  0  0]]

 [[ 0  0  0]
  [11 22 33]
  [ 0  0  0]
  [11 22  0]
  [ 0  0  0]]

 [[ 0  0  0]
  [11 22 33]
  [11  0  0]
  [11 22  0]
  [ 0  0  0]]

 [[ 0  0  0]
  [11 22 33]
  [ 0 22  0]
  [11  0  0]
  [ 0  0  0]]

 [[ 0  0  0]
  [11 22 33]
  [ 0  0  0]
  [11 22  0]
  [ 0  0  0]]

 [[ 0  0  0]
  [11 22 33]
  [ 0  0  0]
  [11 22 33]
  [ 0  0  0]]

 [[ 0  0  0]
  [11 22  0]
  [ 0 22 33]
  [11 22  0]
  [ 0  0  0]]

 [[ 0  0  0]
  [ 0  0  0]
  [ 0  0  0]
  [ 0  0  0]
  [ 0  0  0]]]

我得到了

>>> for i in range(a.shape[2]):
...     print(str(a[:,:,i]) + "\n")
...
[[ 0  0  0  0  0]
 [ 0  0 11  0  0]
 [ 0 11  0 11  0]
 [ 0 11  0 11  0]
 [ 0 11 11 11  0]
 [ 0 11  0 11  0]
 [ 0 11  0 11  0]
 [ 0 11  0 11  0]
 [ 0 11  0 11  0]
 [ 0  0  0  0  0]]

[[ 0  0  0  0  0]
 [ 0 22 22  0  0]
 [ 0 22  0 22  0]
 [ 0 22  0 22  0]
 [ 0 22  0 22  0]
 [ 0 22 22  0  0]
 [ 0 22  0 22  0]
 [ 0 22  0 22  0]
 [ 0 22 22 22  0]
 [ 0  0  0  0  0]]

[[ 0  0  0  0  0]
 [ 0  0 33  0  0]
 [ 0 33  0 33  0]
 [ 0 33  0  0  0]
 [ 0 33  0  0  0]
 [ 0 33  0  0  0]
 [ 0 33  0  0  0]
 [ 0 33  0 33  0]
 [ 0  0 33  0  0]
 [ 0  0  0  0  0]]

然而,如果我遍历轴2并像这样打印,它就像我想要的那样显示:

a

在我看来这更有意义。

所以看起来我的直觉对于轴应该可视化的方式是相反的,而我的数组numpy.set_printoptions应该是形状(3,5,10)。但是,我有一个完整的项目围绕某种格式的数组,所以我现在无法真正改变它。我认为轴的顺序是任意的,这就是为什么我觉得受此限制的原因。那么是否有一些快速甚至内置的方式我可以让NumPy反向或任意顺序打印轴?我查看了Any CPU的文档,但没有发现任何类型。我意识到打印是微不足道的,但是我想绕过所有必须做的切片来好好看看我的数据。或者也许有人可以解释为什么它不是完全随意的,也许我应该以不同的方式思考阵列轴。

2 个答案:

答案 0 :(得分:2)

不幸的是,这不仅仅是在NumPys打印选项中使用简单的开关。你真的必须重新排序轴以获得所需的输出(这很容易)。

如果只是print,你可以简单地在打印功能周围定义一个薄包装器:

import numpy as np

def my_numpy_print(arr):
    if arr.ndim == 3:
        print(arr.transpose(2, 0, 1))
    else:  # no idea how you want it to be displayed for different dimensional arrays.
        print(arr)

arr = ...
my_numpy_print(arr)

输出:

[[[ 0  0  0  0  0]
  [ 0  0 11  0  0]
  [ 0 11  0 11  0]
  [ 0 11  0 11  0]
  [ 0 11 11 11  0]
  [ 0 11  0 11  0]
  [ 0 11  0 11  0]
  [ 0 11  0 11  0]
  [ 0 11  0 11  0]
  [ 0  0  0  0  0]]

 [[ 0  0  0  0  0]
  [ 0 22 22  0  0]
  [ 0 22  0 22  0]
  [ 0 22  0 22  0]
  [ 0 22  0 22  0]
  [ 0 22 22  0  0]
  [ 0 22  0 22  0]
  [ 0 22  0 22  0]
  [ 0 22 22 22  0]
  [ 0  0  0  0  0]]

 [[ 0  0  0  0  0]
  [ 0  0 33  0  0]
  [ 0 33  0 33  0]
  [ 0 33  0  0  0]
  [ 0 33  0  0  0]
  [ 0 33  0  0  0]
  [ 0 33  0  0  0]
  [ 0 33  0 33  0]
  [ 0  0 33  0  0]
  [ 0  0  0  0  0]]]

答案 1 :(得分:1)

MATLAB / Octave会根据需要显示矩阵。第一轴变化最快,最后一轴变慢。

numpy以其他顺序迭代轴。最后一轴变化最快。

从连续数字中创建数组可能有助于可视化差异:

>> x = 1:24;
>> x=reshape(x,2,3,4)
x =
ans(:,:,1) =
   1   3   5
   2   4   6
ans(:,:,2) =
    7    9   11
    8   10   12
ans(:,:,3) =
   13   15   17
   14   16   18
ans(:,:,4) =
   19   21   23
   20   22   24

In [82]: x = np.arange(1,25).reshape(2,3,4)
In [83]: x
Out[83]: 
array([[[ 1,  2,  3,  4],
        [ 5,  6,  7,  8],
        [ 9, 10, 11, 12]],

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

因此在MATLAB中,顺序是(行,列,平面),用于迭代和显示。 numpy是(平面,行,列)。

numpy中,还有另一个变量order

In [85]: x = np.arange(1,25).reshape(2,3,4,order='F')
In [86]: x
Out[86]: 
array([[[ 1,  7, 13, 19],
        [ 3,  9, 15, 21],
        [ 5, 11, 17, 23]],

       [[ 2,  8, 14, 20],
        [ 4, 10, 16, 22],
        [ 6, 12, 18, 24]]])

但是打印仍然是从左到右。

In [115]: for i in range(4): print(x[:,:,i])
[[1 3 5]
 [2 4 6]]
[[ 7  9 11]
 [ 8 10 12]]
[[13 15 17]
 [14 16 18]]
[[19 21 23]
 [20 22 24]]

另一种可视化排序的方法是查看strides

In [119]: x = np.arange(1,25).reshape(2,3,4)
In [120]: x.strides
Out[120]: (48, 16, 4)

要从一列步进到下一列,它会移动4个字节。但是从一个平面到下一个平面是一个48字节(4 * 3 * 4)的步幅。

order F中,步幅以其他顺序递增。

In [121]: np.arange(1,25).reshape(2,3,4,order='F').strides
Out[121]: (4, 8, 24)

我在np.set_printoptions中看不到任何能让我们控制轴排序的东西。我没有定义此打印的位置。