Numpy之如何改变数组形状
作者:大笨牛@
前言
本篇总结、介绍数组的基本操作之一——改变数组形状 。
1. reshape
numpy.reshape(a, newshape, order=‘C')
在不改变数据的情况下为数组赋予新的形状
a
:类数组(array_like)。待重塑数组newshape
:整数(一维数组)或者整数列表/元组(高维数组)等。重塑之后的数组形状(shape)。需要注意的是重塑之后的数组形状要与待重塑数组的形状相容order:{‘C’, ‘F’, ‘A’}
,可选参数。数据在计算机内存中的存储顺序
>>> arr1 = np.arange(8) >>> arr1 array([0, 1, 2, 3, 4, 5, 6, 7]) ## 打印arr1形状 >>> arr1.shape (8,) # 将arr1变换为二维数组 >>> arr2 = np.reshape(arr1,(2,4)) >>> arr2 array([[0, 1, 2, 3], [4, 5, 6, 7]]) ## 打印arr2形状 >>> arr2.shape (2, 4) # 将arr1变换为三维数组 >>> arr3 = np.reshape(arr1,(2,2,2)) >>> arr3 array([[[0, 1], [2, 3]], [[4, 5], [6, 7]]]) ## 打印arr3形状 >>> arr3.shape (2, 2, 2) # 将arr3转换为一维数组 >>> arr4 = np.reshape(arr3,8) >>> arr4 array([0, 1, 2, 3, 4, 5, 6, 7]) ## 打印arr4形状 >>> arr4.shape (8,) # 重塑之后的数组形状要与待重塑数组的形状相容,否则报错 >>> arr5 = np.reshape(arr1,(3,3)) ValueError: cannot reshape array of size 8 into shape (3,3)
注释:
newshape参数的其中一维可以是-1,表示该维度上的长度会自动根据数组的长度及其余维度的长度自动推断出来。
我们看一下下面的例子:
>>> arr1 = np.arange(8) >>> arr1 array([0, 1, 2, 3, 4, 5, 6, 7]) >>> arr2 = np.reshape(arr1,(2,-1)) >>> arr2 array([[0, 1, 2, 3], [4, 5, 6, 7]])
只能其中一维为-1:
>>> arr1 = np.arange(8) >>> arr1 array([0, 1, 2, 3, 4, 5, 6, 7]) >>> arr2 = np.reshape(arr1,(2,-1,-1)) ValueError: can only specify one unknown dimension
另外,需要注意numpy.reshape(a,(1,-1))与numpy.reshape(a,(-1,1))以及numpy.reshape(a,-1)的区别:
>>> arr1 = np.arange(8) >>> arr1 array([0, 1, 2, 3, 4, 5, 6, 7]) # numpy.reshape(a,(1,-1)) >>> arr2 = np.reshape(arr1,(1,-1)) >>> arr2 array([[0, 1, 2, 3, 4, 5, 6, 7]]) >>> arr2.shape (1, 8) # numpy.reshape(a,(-1,1)) >>> arr3 = np.reshape(arr1,(-1,1)) >>> arr3 array([[0], [1], [2], [3], [4], [5], [6], [7]]) >>> arr3.shape (8, 1) # numpy.reshape(a,-1) >>> arr4 = np.reshape(arr3,-1) >>> arr4 array([0, 1, 2, 3, 4, 5, 6, 7]) >>> arr4.shape (8,)
注释:
每个Numpy数组(ndarray)的实例也都有自己的reshape方法(注意与函数reshape区别),其语法如下:
a.reshape(shape, order=‘C’):在不改变数据的情况下为数组赋予新的形状(a为Numpy数组实例)
无论从语法还是功能上来说,Numpy数组的reshape方法和Numpy的reshape函数都一样。
两者的主要区别在于:
(1)Numpy的reshape函数可以直接对诸如python列表对象进行操作(但返回的依然是Numpy ndarray对象),而Numpy数组的reshape方法则不行。
(2)Numpy数组的reshape方法支持形状(shape)参数的每个元素作为单独的参数传入,而Numpy的reshape函数不行。
我们先来看一下第一点:
# numpy.reshape函数 >>> list1 = [0,1,2,3,4,5,6,7,8] >>> arr1 = np.reshape(list1,(3,3)) >>> arr1 array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) # ndarray.reshape方法 >>> list1.reshape(list1,(3,3)) AttributeError: 'list' object has no attribute 'reshape'
我们再来看一下第二点:
# numpy.reshape函数 ## 形状参数作为一个整体传入 >>> arr1 = np.arange(8) >>> np.reshape(arr1,(2,4)) array([[0, 1, 2, 3], [4, 5, 6, 7]]) ## 形状参数单独分开传入 >>> np.reshape(arr1,2,4) TypeError: order must be str, not int
# ndarray.reshape方法 ## 形状参数作为一个整体传入 >>> arr1 = np.arange(8) >>> arr1.reshape((2,4)) array([[0, 1, 2, 3], [4, 5, 6, 7]]) ## 形状参数的元素单独传入 >>> arr1.reshape(2,4) array([[0, 1, 2, 3], [4, 5, 6, 7]])
注释:
numpy.reshape和ndarray.reshape都不会改变原数组的形状。
2. ravel
numpy.ravel(a, order=‘C')
返回展平成一维的数组元素。
一般返回的是数组视图(view),需要的时候(例如order改变)才会返回数组的副本(copy)
a
:类数组order:{‘C’,’F’, ‘A’, ‘K’}
,可选参数
注释:
numpy.ravel和ndarray.ravel以及ndarray.reshape(-1)等同。
>>> arr1 = np.arange(8).reshape(2,2,2) >>> arr1 array([[[0, 1], [2, 3]], [[4, 5], [6, 7]]]) >>> np.ravel(arr1) array([0, 1, 2, 3, 4, 5, 6, 7]) >>> arr1.ravel() array([0, 1, 2, 3, 4, 5, 6, 7]) >>> arr1.reshape(-1) array([0, 1, 2, 3, 4, 5, 6, 7])
3. ndarray.flatten
ndarray.flatten(order=‘C')
返回坍塌成一维的数组的副本
order:{‘C’, ‘F’, ‘A’, ‘K’}
,可选参数
>>> arr1 = np.arange(8).reshape(2,2,2) >>> arr1 array([[[0, 1], [2, 3]], [[4, 5], [6, 7]]]) >>> arr1.flatten() array([0, 1, 2, 3, 4, 5, 6, 7])
注释:
有关ravel和ndarray.flatten的区别和联系:
- numpy.ravel、ndarray.ravel、ndarray.reshape(-1)以及ndarray.flatten都可以返回展平成一维的数组元素
- numpy.ravel、ndarray.ravel、ndarray.reshape(-1)返回的是数组的视图,而ndarray.flatten返回的是数组的副本
>>> arr1 = np.arange(8).reshape(2,2,2) >>> arr1 array([[[0, 1], [2, 3]], [[4, 5], [6, 7]]]) >>> arr2 = arr1.reshape(-1) >>> arr2 array([0, 1, 2, 3, 4, 5, 6, 7]) >>> arr3 = arr1.ravel() >>> arr3 array([0, 1, 2, 3, 4, 5, 6, 7]) >>> arr4 = arr1.flatten() >>> arr4 array([0, 1, 2, 3, 4, 5, 6, 7]) >>> arr5 = arr1.ravel(order='F') >>> arr5 array([0, 4, 2, 6, 1, 5, 3, 7]) >>> arr1[0][0][1] = -1 # arr1改变后 >>> arr1 array([[[ 0, -1], [ 2, 3]], [[ 4, 5], [ 6, 7]]]) >>> arr2 array([ 0, -1, 2, 3, 4, 5, 6, 7]) >>> arr3 array([ 0, -1, 2, 3, 4, 5, 6, 7]) >>> arr4 array([0, 1, 2, 3, 4, 5, 6, 7]) >>> arr5 array([0, 4, 2, 6, 1, 5, 3, 7])
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
Reference
[1]: https://numpy.org/doc/stable/reference/routines.array-manipulation.html
[2]: https://www.runoob.com/numpy/numpy-copies-and-views.html