Numpy
是整个Python
的科学计算的基础,撑起了Python
作为机器学习重要语言的整个计算基础,包括Numpy
, Scipy
, Pandas
, Scikit-Learn
以及最近兴起的机器学习和深度学习库,包括TensorFlow
, Keras
等,它们多维数据的表示和使用无不基于Numpy
,因此在语法和使用上以及功能上都和Numpy
有着很多相似之处,这篇文章介绍Numpy
中的非常重要的概念,那就是axis
,如果你完全理解了axis
,那么操作起多维的数组的时候将得心应手。
Numpy
的主要对象是同质多维数组,在Numpy
中,维度(dimensions
)被称作轴(axes
),轴(axes
)的值就是秩(rank
, 要区别与线性代数的矩阵的秩),比如数组[1, 2, 1]
的维度就是1,它有1个轴,它的秩是1,而轴的长度是3。下面的例子当中,
1 2 3 |
In [1]: import numpy as np In [2]: data = np.array([[ 1., 0., 0.], [ 0., 1., 2.]]) |
data
的维度是2,秩的值也是2,其中第一个维度(轴)的长度是2,第二个维度(轴)的长度是3。再比如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
In [3]: data2 = np.random.randint(0, 5, [2,3,2,3]) In [4]: data2 Out[4]: array([[[[4, 4, 4], [3, 2, 2]], [[0, 4, 0], [1, 4, 1]], [[2, 3, 3], [3, 3, 4]]], [[[2, 1, 1], [0, 4, 4]], [[1, 1, 0], [3, 4, 1]], [[2, 1, 1], [4, 0, 0]]]]) |
data2
的维度是4,如下代码所示,其中,第一个维度的长度是2,第二个维度的长度是3,第三个维度的长度是2,第四个维度的长度是2。
1 2 |
In [5]: data2.ndim Out[5]: 4 |
Numpy
数组的名字叫ndarray
,它的主要的属性如下
文档原文为:
- ndarray.ndim
the number of axes (dimensions) of the array. In the Python world, the number of dimensions is referred to as rank. - ndarray.shape
the dimensions of the array. This is a tuple of integers indicating the size of the array in each dimension. For a matrix with n rows and m columns, shape will be (n,m). The length of the shape tuple is therefore the rank, or number of dimensions, ndim. - ndarray.size
the total number of elements of the array. This is equal to the product of the elements of shape. - ndarray.dtype
an object describing the type of the elements in the array. One can create or specify dtype’s using standard Python types. Additionally NumPy provides types of its own. numpy.int32, numpy.int16, and numpy.float64 are some examples. - ndarray.itemsize
the size in bytes of each element of the array. For example, an array of elements of type float64 has itemsize 8 (=64/8), while one of type complex32has itemsize 4 (=32/8). It is equivalent to ndarray.dtype.itemsize. - ndarray.data
the buffer containing the actual elements of the array. Normally, we won’t need to use this attribute because we will access the elements in an array using indexing facilities.
给个求和的例子
1 2 3 4 5 6 7 |
In [57]: data = np.array([[1,2,1], ...: [0,3,1], ...: [2,1,4], ...: [1,3,1]]) In [58]: np.sum(data, axis=0) Out[58]: array([4, 9, 7]) |
上面的代码表示按照第一个维度求和,也即axis=0
,就是按照axis=0
这个方向求和,那么得到的结果是axis=0
这个轴消失,最后的shape
是(3, )
。再看这个例子
1 2 |
In [59]: np.sum(data, axis=1) Out[59]: array([4, 4, 7, 5]) |
从axis=1
这个方向求和,那么axis=1
这个轴消失,最后得到的结果的shape
是(4,)
。可以总结为一句话:设axis=i
,则numpy
沿着第i个下标变化的方向进行操作。
再举一个例子,numpy
的求和操作sum
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
In [36]: data2 = np.random.randint(0, 5, [2,3,2,3]) In [37]: data2 Out[37]: array([[[[2, 3, 2], [1, 0, 1]], [[0, 0, 4], [3, 1, 4]], [[4, 1, 2], [2, 3, 3]]], [[[4, 1, 4], [3, 1, 0]], [[0, 1, 2], [3, 1, 0]], [[4, 0, 4], [3, 4, 0]]]]) |
data2有四个aixs,这里分别对axis=0,1,2,3进行求和操作
1 2 3 4 5 6 7 8 9 10 11 12 13 |
In [38]: data2.sum(axis=0) Out[38]: array([[[6, 4, 6], [4, 1, 1]], [[0, 1, 6], [6, 2, 4]], [[8, 1, 6], [5, 7, 3]]]) In [39]: data2.sum(axis=0).shape Out[39]: (3, 2, 3) |
可以看到axis=0这一轴消失了,再看其他的结果
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 |
In [43]: data2.sum(axis=1) Out[43]: array([[[ 6, 4, 8], [ 6, 4, 8]], [[ 8, 2, 10], [ 9, 6, 0]]]) In [44]: data2.sum(axis=1).shape Out[44]: (2, 2, 3) In [45]: data2.sum(axis=2) Out[45]: array([[[3, 3, 3], [3, 1, 8], [6, 4, 5]], [[7, 2, 4], [3, 2, 2], [7, 4, 4]]]) In [46]: data2.sum(axis=2).shape Out[46]: (2, 3, 3) In [47]: data2.sum(axis=3) Out[47]: array([[[7, 2], [4, 8], [7, 8]], [[9, 4], [3, 4], [8, 7]]]) In [48]: data2.sum(axis=3).shape Out[48]: (2, 3, 2) |
这里我的理解是当一个轴消除时,为了保持其他的轴不变,那么所做的操作必须迁就下一个轴,与前前面的轴无关。
参考资料