numpy 学习:数组改变形状、副本和view

一个数组的形状是由每个轴的元素数量决定的,可以通过reshape()和resize()函数来操纵数组的形状。transpose()函数用于数组的转置,ravel()函数用于把数组展开为一维数组,而flatten()用于获得数组展开之后的一个副本;swapaxes()函数用于交换数组的两个轴,squeeze()函数用于删除数组中长度为1的轴。

一,数组的变形

数组的转置可以通过数组的属性T来获得,数组的展开可以通过数组的属性flat来获得,但是flat是一个迭代器。

1,通过修改shape属性来改变数组的形状

numpy.ndarray.shape表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 ndim 属性(秩)。

x = np.array([1, 2, 9, 4, 5, 6, 7, 8])
print(x.shape)  # (8,)
x.shape = [2, 4]

2,reshape函数

reshape()函数返回一个给定shape的数组的副本,不会修改原始数组,并且新的数组的size必须跟原始的数组size相兼容:

numpy.reshape(a, newshape, order='C')

参数 newshape 表示数组的形状,对于二维数组,newshape是 (row, col) ,第一个维度是行数,第二个维度是列数。

例如,下面的代码把一个一维数组转换为4行2列的二位数组:

a=np.arange(8)
a.reshape((4,2))

3,resize函数

resize()函数会修改原始数组,不会返回任何数据,直接对原始数组进行修改:

ndarray.resize(new_shape, refcheck=True)

参数new_shape是元组或n个int数字,表示数组的形状,即各个维度的元素数量,如果参数new_shape指定的size大于现有数组的size,那么新数组会增加新的元素,新增加的元素值都是0

>>> a.resize((2,6))
>>> a
array([[ 2.,  8.,  0.,  6.,  4.,  5.],
       [ 1.,  1.,  8.,  9.,  3.,  6.]])

4,展开数组

numpy.ndarray.flat 将数组转换为一维的迭代器,可以用for访问数组每一个元素.

y = x.flat
for i in y:
    print(i, end=' ')

numpy.ndarray.flatten() 将数组的副本转换为一维数组,并返回原数组的一个copy。

numpy.ndarray.ravel() 用于返回数组的展开形式,在展开成一维数组时,最右边的索引“变化最快”,返回原始数组的一个view。

ndarray.ravel()
ndarray.flatten()

举个例子,从行维度和列维度的最小值开始,依次增加,获取的元素依次排列,构成一维数组:

>>> x = np.array([[1, 2, 3], [4, 5, 6]])
>>> np.ravel(x)
array([1, 2, 3, 4, 5, 6])

5,转置

数组的转置(Transpose)通过ndarray的属性T来获取:

>>> x = np.array([[1.,2.],[3.,4.]])
>>> x
array([[ 1.,  2.],
       [ 3.,  4.]])
>>> x.T
array([[ 1.,  3.],
       [ 2.,  4.]])

变换数组的维度,对于二维数组,转置是把行坐标和列坐标互换:

numpy.transpose(a, axes=None)

对于多维数组,转置需要指定新转换的维度,比如,对于三维数组,用0、1、2表示各个维度,(1,0,2)表示:把列维度变换为行维度,把行维度变化为列维度,第三维度不变。

>>> x = np.ones((1, 2, 3))
>>> np.transpose(x, (1, 0, 2)).shape
(2, 1, 3)

6,交换轴

把数组的两个轴相互交换

numpy.swapaxes(a, axis1, axis2)

7,移除长度为1的轴

从数组的shape中删除值为1的维度。

>>> x = np.array([[[0], [1], [2]]])
>>> x.shape
(1, 3, 1)
>>> np.squeeze(x).shape
(3,)
>>> np.squeeze(x, axis=0).shape
(3, 1)

二,数组的转换

可以把数组转换为list,也可以修改数组元素的数据类型。

1,转换为list

ndarray对象的tolist()函数可以把一个数组对象转化为list列表:

>>> np.arange(12).reshape(3,4).tolist()
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]

2,修改元素的类型

调用astype()函数会创建一个新的数组,是原始数组的一个深拷贝。

arr.astype(np.int8)

三,数组的副本(copy)和视图(view)

在做数组运算或数组操作时,返回的结果不是数组的副本就是视图。

  • 直接赋值:无拷贝,相当于是引用
  • view():建立视图,浅拷贝,形状可以不一致,但数据相同,对于赋值和view操作,两个数组的数据是共享的,即引用同一个对象。
  • copy():深拷贝,完全独立的对象

数组的视图意味着数据不会被复制,视图上的任何修改都会直接反应到原始数组上。

view_arr = arr.view()

numpy.ndarray.copy() 函数创建一个副本。 对副本数据进行修改,不会影响到原始数据,它们物理内存不在同一位置。

deep_copy_arr = arr.copy()

参考文档:

作者悦光阴
本文版权归作者和博客园所有,欢迎转载,但未经作者同意,必须保留此段声明,且在文章页面醒目位置显示原文连接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/ljhdo/p/15755417.html