【Numpy】改变数组形状

前言

本篇总结、介绍数组的基本操作之一——改变数组形状 [1]

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) [2]

  • 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值