NumPy相关数组操作

1年前 (2024-04-27)

NumPy 中包含了一些处理数组的常用方法,大致可分为以下几类:

  • 数组变维操作

  • 数组转置操作

  • 修改数组维度操作

  • 连接与分割数组操作


下面分别对它们进行介绍。

数组变维操作

数组变维操作

函数名称

函数介绍

reshape

在不改变数组元素的条件下,修改数组的形状。

flat

返回是一个迭代器,可以用 for 循环遍历其中的每一个元素。

flatten

以一维数组的形式返回一份数组的副本,对副本的操作不会影响到原数组。

ravel

返回一个连续的扁平数组(即展开的一维数组),与 flatten不同,它返回的是数组视图(修改视图会影响原数组)。


reshape 在《NumPy ndarray对象》一节已经做了讲解,本节不再介绍。

1) numpy.ndarray.flat

numpy.ndarray.flat 返回一个数组迭代器,实例如下:

import numpy as np

a = np.arange(9).reshape(3,3)

for row in a:

print (row)

#使用flat属性:

for ele in a.flat:

print (ele,end=",")

输出结果如下:

#原数组

[0 1 2]

[3 4 5]

[6 7 8]

#输出元素

0,1,2,3,4,5,6,7,8,

2) numpy.ndarray.flatten()

numpy.ndarray.flatten 返回一份数组副本,对副本修改不会影响原始数组,其语法格式如下:

ndarray.flatten(order='C')

实例如下:

import numpy as np

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

print (a)

#默认按行C风格展开的数组

print (a.flatten())

#以F风格顺序展开的数组

print (a.flatten(order = 'F'))

输出结果:

#数组a

[[0 1 2 3]

[4 5 6 7]]

#默认c顺序站看数组

[0 1 2 3 4 5 6 7]

# F顺序站看数组

[0 4 1 5 2 6 3 7]

3) numpy.ravel()

numpy.ravel() 将多维数组中的元素以一维数组的形式展开,该方法返回数组的视图(view),如果修改,则会影响原始数组。

numpy.ravel(a, order='C')

实例结果如下:

import numpy as np

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

print ('原数组:')

print (a)

print ('调用 ravel 函数后:')

print (a.ravel())

print ('F 风格顺序调用 ravel 函数之后:')

print (a.ravel(order = 'F'))

输出结果如下:

原数组:

[[0 1 2 3]

[4 5 6 7]]

调用 ravel 函数后:

[0 1 2 3 4 5 6 7]

F 风格顺序调用 ravel 函数之后:

[0 4 1 5 2 6 3 7]

数组转置操作

数组转置操作

函数名称

说明

transpose

将数组的维度值进行对换,比如二维数组维度(2,4)使用该方法后为(4,2)。

ndarray.T

与 transpose 方法相同。

rollaxis

沿着指定的轴向后滚动规定的位置。

swapaxes

对数组的轴进行对换。

1) numpy.transpose()

numpy.transpose() 用于对换多维数组的维度,比如二维数组使用此方法可以实现矩阵转置,语法格式如下:

numpy.transpose(arr, axes)

参数说明如下:

  • arr:要操作的数组

  • axes:可选参数,元组或者整数列表,将会按照该参数进行转置。


示例如下:

import numpy as np

a = np.arange(12).reshape(3,4)

print (a)

print (np.transpose(a))

输出结果:

原数组:

[[ 0 1 2 3]

[ 4 5 6 7]

[ 8 9 10 11]]

对换数组:

[[ 0 4 8]

[ 1 5 9]

[ 2 6 10]

[ 3 7 11]]

ndarray.T 的使用方法与其类似,这里就在赘述。

2) numpy.rollaxis()

该方法表示沿着指定的轴,向后滚动一个特定位置,格式如下:

numpy.rollaxis(arr, axis, start)

参数说明:

  • arr:要传入的数组;

  • axis:沿着哪条轴向后滚动,其它轴的相对位置不会改变;

  • start:默认以 0 轴开始,可以根据数组维度调整它的值。

3) numpy.swapaxes()

该方法用于交换数组的两个轴,其语法格式如下:

numpy.swapaxes(arr, axis1, axis2) 

示例如:

import numpy as np

# 创建了三维的 ndarray

a = np.arange(27).reshape(3,3,3)

print (a)

#对换0轴与2轴

print(np.swapaxes(a,2,0))

输出结果:

#原a数组

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

#对换轴后的数组

[[[ 0 9 18]

[ 3 12 21]

[ 6 15 24]]

[[ 1 10 19]

[ 4 13 22]

[ 7 16 25]]

[[ 2 11 20]

[ 5 14 23]

[ 8 17 26]]]

修改数组维度操作

修改数组维度的操作,主要有以下方法:

数组维度修改

函数名称

描述说明

broadcast

生成一个模拟广播的对象。

broadcast_to

将数组广播为新的形状。

expand_dims

扩展数组的形状。

squeeze

从数组的形状中删除一维项。

1) numpy.broadcast()

返回值是数组被广播后的对象,该函数以两个数组作为输入参数,实例如下:

import numpy as np

a = np.array([[1], [2], [3]])

b = np.array([4, 5, 6])

# 对b广播a

d = np.broadcast(a,b)

#d它拥有 iterator 属性

r,c = d.iters

print (next(r), next(c))

print (next(r), next(c))

# 使用broadcast将a与b相加

e = np.broadcast(a,b)

f=np.empty(e.shape)

f.flat=[x+y for (x,y) in e]

print(f)

print(a+b)

输出结果:

#对b广播a

1 6

2 4

#f数组

[[5. 6. 7.]

[6. 7. 8.]

[7. 8. 9.]]

#a+b

[[5 6 7]

[6 7 8]

[7 8 9]]

2) numpy.broadcast_to()

该函数将数组广播到新形状中,它在原始数组的基础上返回一个只读视图。 如果新形状不符 NumPy 的广播规则,则会抛出 ValueError 异常。函数的语法格式如下:

numpy.broadcast_to(array, shape, subok)

使用实例如下所示:

import numpy as np

a = np.arange(4).reshape(1,4)

print("原数组",a)

print ('调用 broadcast_to 函数之后:')

print (np.broadcast_to(a,(4,4)))

的输出结果如下:

#原数组

[[0 1 2 3]]

#调用 broadcast_to 函数之后:

[[0 1 2 3]

[0 1 2 3]

[0 1 2 3]

[0 1 2 3]]

3) numpy.expand_dims()

在指定位置插入新的轴,从而扩展数组的维度,语法格式如下:

numpy.expand_dims(arr, axis)

参数说明:

  • arr:输入数组

  • axis:新轴插入的位置


实例如下:

import numpy as np

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

print ('数组 x:')

print (x)

# 在 0 轴处插入新的轴

y = np.expand_dims(x, axis = 0)

print ('数组 y:')

print (y)

print ('\n')

print ('数组 x 和 y 的形状:')

print (x.shape, y.shape)

输出结果为:

数组 x:

[[1 2]

[3 4]]

数组 y:

[[[1 2]

[3 4]]]

数组 x 和 y 的形状:

(2, 2) (1, 2, 2)

4) numpy.squeeze()

删除数组中维度为 1 的项,例如,一个数组的 shape 是 (5,1),经此函数后,shape 变为 (5,) 。其函数语法格式如下:

numpy.squeeze(arr, axis)

参数说明:

  • arr:输入数的组;

  • axis:取值为整数或整数元组,用于指定需要删除的维度所在轴,指定的维度值必须为 1 ,否则将会报错,若为 None,则删除数组维度中所有为 1 的项。


下面是带有 axis 参数的实例:

>>> x = np.array([[[0], [1], [2]]])

>>> x.shape

(1, 3, 1)

>>> np.squeeze(x).shape

(3,)

>>> np.squeeze(x, axis=(2,)).shape

(1, 3)

再看另一组示例,如下所示:

import numpy as np

a = np.arange(9).reshape(1,3,3)

print (a)

b = np.squeeze(a)

print (b)

print ('数组 a 和 b 的形状:')

print (x.shape, y.shape)

输出结果为:

数组 a:

[[[0 1 2]

[3 4 5]

[6 7 8]]]

数组 b:

[[0 1 2]

[3 4 5]

[6 7 8]]

数组 a 和 b 的形状:

(1, 3, 3) (3, 3)

连接与分割数组操作

连接与分割数组是数组的两种操作方式,我们为了便于大家记忆,现将它们的方法整在一起,如下所示:

 

连接与分割数组

类型

函数名称

描述说明

连接数组方法

concatenate

沿指定轴连接两个或者多个相同形状的数组

stack

沿着新的轴连接一系列数组

hstack

按水平顺序堆叠序列中数组(列方向)

vstack

按垂直方向堆叠序列中数组(行方向)

分割数组方法

split

将一个数组分割为多个子数组

hsplit

将一个数组水平分割为多个子数组(按列)

vsplit

将一个数组垂直分割为多个子数组(按行)

1) 连接数组操作

numpy.concatenate() 沿指定轴连接相同形状的两个或多个数组,格式如下:

numpy.concatenate((a1, a2, ...), axis)

参数说明:

  • a1, a2, ...:表示一系列相同类型的数组;

  • axis:沿着该参数指定的轴连接数组,默认为 0。


实例说明:创建两个 a 、b 数组,并沿指定轴将它们连接起来。注意两个数组的形状要保持一致。

import numpy as np

#创建数组a

a = np.array([[10,20],[30,40]])

print (a)

#创建数组b

b = np.array([[50,60],[70,80]])

print (b)

#沿轴 0 连接两个数组

print (np.concatenate((a,b)))

#沿轴 1 连接两个数组

print (np.concatenate((a,b),axis = 1))

输出结果:

#a

[[10 20]

[30 40]]

#b

[[50 60]

[70 80]]

#axis=0沿着垂直方向

[[10 20]

[30 40]

[50 60]

[70 80]]

#axis=1沿着水平方向

[[10 20 50 60]

[30 40 70 80]]

数组连接操作少需要两个维度相同的数组,才允许对它们进行垂直或者水平方向上的操作。

在垂直方向堆叠数组,示例如下:

import numpy as np

a = np.array([[1,2],[3,4]])

b = np.array([[5,6],[7,8]])

#垂直堆叠

c = np.vstack((a,b))

print (c)

输出结果如下:

[[1 2]
[3 4]
[5 6]

[7 8]]

2) 分割数组操作

numpy.split() 沿指定的轴将数组分割为多个子数组,语法格式如下:

numpy.split(ary, indices_or_sections, axis)

参数说明:

  • ary:被分割的数组

  • indices_or_sections:若是一个整数,代表用该整数平均切分,若是一个数组,则代表沿轴切分的位置(左开右闭);

  • axis:默认为0,表示横向切分;为1时表示纵向切分。


示例如下所示:

import numpy as np

a = np.arange(6)

#原数组

print (a)

#将数组分为二个形状大小相等的子数组

b = np.split(a,2)

print (b)

#将数组在一维数组中标明要位置分割

b = np.split(a,[3,4])

print (b)

输出结果如下:

#a数组

[0 1 2 3 4 5]

#切分分形状大小相同的数组

[array([0, 1, 2]), array([3, 4, 5])]

#按数组标明位置切分,切分时左开右闭

[array([0, 1, 2]), array([3]), array([4, 5])]

看一下 hsplit() 的使用方法,示例如下:

import numpy as np

#arr1数组

arr1 = np.floor(10 * np.random.random((2, 6)))

print(arr1)

#拆分后数组

print(np.hsplit(arr1, 3))

输出结果:

#原arr1数组

[[2. 1. 5. 3. 1. 7.]

[1. 2. 9. 0. 9. 9.]]

#经过水平切分后得到的数组

[array([[2., 1.],

[1., 2.]]), array([[5., 3.],

[9., 0.]]), array([[1., 7.],

[9., 9.]])]]