改变数组的形状
一个数组的形状是由每个轴的元素数量决定的:
>>> a = np.floor(10*np.random.random((3,4)))
>>> a
array([[ 2., 8., 0., 6.],
[ 4., 5., 1., 1.],
[ 8., 9., 3., 6.]])
>>> a.shape
(3, 4)
可以使用各种命令更改数组的形状。请注意,以下三个命令都返回一个修改后的数组,但不会更改原始数组:
>>> a.ravel() # returns the array, flattened
array([ 2., 8., 0., 6., 4., 5., 1., 1., 8., 9., 3., 6.])
>>> a.flatten() # returns the array, flattened deep copy
array([ 2., 8., 0., 6., 4., 5., 1., 1., 8., 9., 3., 6.])
>>> a.reshape(6,2) # returns the array with a modified shape
array([[ 2., 8.],
[ 0., 6.],
[ 4., 5.],
[ 1., 1.],
[ 8., 9.],
[ 3., 6.]])
>>> a.T # returns the array, transposed
array([[ 2., 4., 8.],
[ 8., 5., 9.],
[ 0., 1., 3.],
[ 6., 1., 6.]])
>>> a.T.shape
(4, 3)
>>> a.shape
(3, 4)
ravel与flatten两者所要实现的功能是一致的(将多维数组降位一维)。这点从两个单词的意也可以看出来,ravel(散开,解开),flatten(变平)。两者的区别在于返回拷贝(copy)还是返回视图(view),numpy.flatten()返回一份拷贝,对拷贝所做的修改不会影响(reflects)原始矩阵,而numpy.ravel()返回的是视图(可理解浅拷贝),会影响(reflects)原始矩阵。
>>> b = a.ravel()
>>> c = a.flatten()
>>> a[0,0] = -1
>>> b
array([-1., 6., 2., 0., 2., 5., 2., 2., 8., 4., 7.,
3.])
>>> c
array([3., 6., 2., 0., 2., 5., 2., 2., 8., 4., 7., 3.])
reshape
:有返回值,所谓有返回值,即不对原始多维数组进行修改;
resize
:无返回值,所谓无返回值,即会对原始多维数组进行修改;
>>> a
array([[ 2., 8., 0., 6.],
[ 4., 5., 1., 1.],
[ 8., 9., 3., 6.]])
>>> a.resize((2,6))
>>> a
array([[ 2., 8., 0., 6., 4., 5.],
[ 1., 1., 8., 9., 3., 6.]])
如果在 reshape 操作中将 size 指定为-1,则会自动计算其他的 size 大小:
>>> a.reshape(3,-1)
array([[ 2., 8., 0., 6.],
[ 4., 5., 1., 1.],
[ 8., 9., 3., 6.]])
另外一个常见的变形模式是将一个一维数组转变为二维的行或列的矩阵。可以通过reshape
方法实现,或者更简单地在一个切片操作中利用newaxis
关键字。
>>> x = np.array([1,2,3])
>>> x.shape
(3,)
>>> a = x.reshape((1,3)) #通过变形获得行向量
>>> a
array([[1, 2, 3]])
>>> a.shape
(1, 3)
>>> a = x.reshape((3,1)) #通过变形获得列向量
>>> a
array([[1],
[2],
[3]])
>>> a.shape
(3, 1)
>>> ###############华丽的分割线################
>>> b = x[np.newaxis,:] #通过newaxis获得的行向量
>>> b
array([[1, 2, 3]])
>>> b.shape
(1, 3)
>>> b = x[:,np.newaxis] #通过newaxis获得的列向量
>>> b
array([[1],
[2],
[3]])
>>> b.shape
(3, 1)