numpy 维度与轴

2016/01/01 Python

我知道 numpy 是多维数组,但是一直不理解其轴 axis 的概念,以及基于轴之上的计算。今天写了些实例终于理解了。

维度

首先是维度,对人来说高维空间是很难想象的,但是我们可以从纯数学的角度来看。对多维数组来说,确定最底层的一个基本元素位置需要用到的索引个数即是维度。

比如说:

array([[1,2],
[3,4]])

要获取 1 的值,我们需要使用 a[0][0], 一共用到了两个坐标索引,所以这个数组的维度是2维,直观的说数组的维度就是所有基本元素左边 [ 个数的最大值。

而每个坐标索引可取的值是有范围的,比如这里两个索引都只能取 0 和 1。维度与坐标值范围就组成了多维数组的 shape 属性,它是一个元组,长度代表了维度,而元组的每一个值代表了一个坐标索引可取的值个数,所以将 shape 的所有值乘起来就可以算出多维数组元素的个数。

对一般的多维数组来说基本元素即是数字,但数字不一定是基本元素,下边接着说。

基本元素

>>> a = array([[1,[1,2]],[3,4]])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: setting an array element with a sequence.
>>> a = array([[[1,2],1],[3,4]])
>>> a
array([[[1, 2], 1],
       [3, 4]], dtype=object)
>>> a.shape
(2, 2)

两次创建,一次失败,一次成功,注意到成功的那个多维数组中 dtype=object 而且 shape(2,2),所以实际上 [1,2] 这个list是被当做多维数组的基本元素的。

至于两次结果不同的原因还不明确,与多维数组的创建过程有关,待确认。

终于来到比较难懂的轴了,先从坐标轴说起。

n 维空间里有 n 个坐标轴,并且坐标轴互相垂直,每一个点相对于一条坐标轴都有唯一的一个坐标值。对同一条坐标轴来说,坐标值相同的点在同一个 n-1 维的“平面”上。任意取一个“平面”,我们就能定义“同一个坐标轴上的点”,这些点在“平面”上的投影相同,同一个坐标轴上的点组成的线是与坐标轴平行的。而所谓的延轴计算实际上是降维的过程,同一个坐标轴上的点合并成一个点,这样n维空间就变成了 n-1 维空间。

具体到 numpy 中的多维数组来说,轴即是元素坐标的索引。比如,第0轴即是第1个索引,延0轴计算就是去掉坐标中的第一个索引。过程就是

  1. 遍历其他索引的所有可能组合
  2. 取出一个组合,保持值不变,遍历第一个索引所有可能值
  3. 根据索引可以获得了同一个轴上的所有元素
  4. 对他们进行计算得到最后的元素
  5. 所有组合的最后结果组到一起就是最后的 n-1 维数组

所以如果一个多维数组的 shape 是 (a1, a2, a3, a4), 那么延轴0计算最后的数组shape 是 (a2, a3, a4), 延轴1计算最后的数组shape是 (a1, a3, a4)

示例:

```python

a = array([[[1,1],[2,1],[3,1]],[[4,1],[5,1],[6,1]],[[7,1],[8,1],[9,1]]]) a.shape (3, 3, 2) a array([[[1, 1], [2, 1], [3, 1]],

   [[4, 1],
    [5, 1],
    [6, 1]],

   [[7, 1],
    [8, 1],
    [9, 1]]]) >>> sum(a, axis=0) array([[12,  3],
   [15,  3],
   [18,  3]]) >>> sum(a, axis=1) array([[ 6,  3],
   [15,  3],
   [24,  3]]) >>> sum(a, axis=2) array([[ 2,  3,  4],
   [ 5,  6,  7],
   [ 8,  9, 10]]) ```### 补充 numpy 的打印结果规则是:
  1. 最后的轴从左往右打印, 所以“列数”是 shape[-1]
  2. 次后的轴从顶向下打印,所以未分割的块行数是 shape[-2]
  3. 剩下的轴从顶向下,每个切片通过一个空行与下一个隔开,所以整个的输出结果可以分成shap[0]块,然后每一块又能分成 shape[1]块

Search

    Table of Contents