Numpy 学习笔记

前言

NumPy 是 Python 中科学计算的基础包。它是一个 Python 库,提供多维数组对象,各种派生对象(如掩码数组和矩阵),以及用于数组快速操作的各种 API,有包括数学、逻辑、形状操作、排序、选择、输入输出、离散傅立叶变换、基本线性代数,基本统计运算和随机模拟等等。

在学习 numpy 之前,你总得在 python 上装上 numpy 吧,安装命令非常简单:

1
pip install numpy

安装完成之后,只需要这样:

1
import numpy

当然更多人的选择是这样,简单一点总是友好的。

1
import numpy as np

一个例子

1
2
3
4
5
6
7
8
9
10
11
12
>>> import numpy as np
>>> a = np.arange(15).reshape(3,5)
>>> a
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> a.shape
(3, 5)
>>> a.dtype
dtype('int32')
>>> a.size
15

创建数组

NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。ndarray 对象是用于存放同类型元素的多维数组。ndarray 中的每个元素在内存中都有相同存储大小的区域。

最开始的命令当然是要学习如何创建一个数组,只有创建了一个数组之后,才能愉快的玩耍

1
2
3
4
# 1维数组
a = np.array([1, 2, 3, 4, 5]) # >>> [1, 2, 3, 4, 5]
b = np.array((1, 2, 3, 4, 5)) # >>> [1, 2, 3, 4, 5]
c = np.arange(1, 6) # >>> [1, 2, 3, 4, 5]

上面的代码显示了创建数组的几种不同方法,最基本的方法是将序列传递给 NumPy 的 array()函数。

注意,单纯传入一串数字是错误的

1
2
a = np.array([1, 2, 3, 4, 5])       # ✔
a = np.array(1, 2, 3, 4, 5) # ✖

类似的,你也可以通过传入多个序列或者嵌套,来构造二维数组以及多维数组

1
2
3
4
a = np.array([[ 0,  1,  2,  3,  4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
a = np.arange(15).reshape(3,5)

很明显,手动输入一个有序的数组无疑是非常麻烦的,因此可以使用 arange()reshape() 更快速的创建矩阵

另外,你也可以在创建时,指定 dtype 显式指定数组的类型:

1
a = np.array([1.5, 2, 3], [4.5, 5, 6], dtype = float)

NumPy 提供了几个函数来创建具有初始占位符内容的数组。

例如 zeros(), ones(), full(), linspace(), eye()

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
27
28
29
30
# 函数 zeros 创建一个由 0 组成的指定大小的数组, 注意括号
>>> np.zeros([2, 3])
array([[0., 0., 0.],
[0., 0., 0.]])

# 函数 ones 创建一个由 1 组成的指定大小的数组, 注意括号
>>> np.ones([2, 3])
array([[1., 1., 1.],
[1., 1., 1.]])

# 函数 full 创建一个全是指定元素的数组
>>> np.full((2, 3), 7)
array([[7, 7, 7],
[7, 7, 7]])

# 使用 linspace 函数来接收我们想要的元素数量的函数
# linspace(start, end, num)
>>> np.linspace(0, 2, 9)
array([0. , 0.25, 0.5 , 0.75, 1. , 1.25, 1.5 , 1.75, 2. ])

# 使用 eye 创建主对角矩阵
>>> np.eye(3)
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])

# 使用 random 构建随机数组
>>> np.random.random((2,3))
array([[0.03258815, 0.15250532, 0.4428446 ],
[0.55359382, 0.3802597 , 0.67287016]])

数组属性

在最开始的例子中,我们使用了 shape, size, dtype 等的属性,通过其属性访问数组也显得非常方便快捷,下面是一些示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
>>> a = np.arange(15).reshape(3,5)
>>> a
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> a.shape # 数组的维度
(3, 5)
>>> len(a) # 数组的长度
3
>>> a.ndim # 数组维数
2
>>> a.dtype # 数组元素的数据类型
dtype('int32')
>>> a.size # 数组中的元素数
15
>>> a.T # 数组转置
array([[ 0, 5, 10],
[ 1, 6, 11],
[ 2, 7, 12],
[ 3, 8, 13],
[ 4, 9, 14]])

基本操作

基本操作符

在创建了数组之后,我们就可以对数组进行操作,加减乘除等,你可以像平常使用 +-×÷ 一样来进行数组计算。

1
2
3
4
5
6
7
8
9
>>> a = np.array([1, 2, 3, 4, 5])
>>> b = np.arange(10, 15)

>>> a + b
>>> a - b
>>> a * b
>>> a / b
>>> a ** 2
>>> a > b

注意,上面的操作符都是对数组进行逐元素运算

如果你需要计算矩阵乘法,请使用 dot() 函数

1
>>> a.dot(b)        # 矩阵乘法

特殊运算符

NumPy 还提供了一些别的用于处理数组的好用的运算符。

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> a = np.array([[1, 2, 3], [4, 5, 6]])
>>> a.sum() # 返回数组元素的总和
21
>>> a.sum(0) # 返回给定轴上的数组元素的总和
array([5, 7, 9])
>>> a.min() # 返回最小值
1
>>> a.argmax() # 返回最大值的索引
5
>>> a.mean(1) # 返回给定轴上的数组元素的平均值
array([2., 5.])
>>> a.cumsum() # 返回给定轴上元素的累积和
array([ 1, 3, 6, 10, 15, 21], dtype=int32)

切片和索引

ndarray 对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样。ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。

对数组进行切片索引就像列表或任何其他 Python 序列一样。如果你熟悉 Python,我想你并不会对他们感到陌生。

在对多维数组进行索引或切片时,通过对每个以逗号分隔的维度执行单独的切片,就像 Matlab 一样

1
2
3
4
5
6
7
8
9
10
11
12
>>> a = np.arange(15).reshape(3,5)
>>> a
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> a[2, 3] # 第 2 行,第 3 列
13
>>> a[0, 1:4] # 第 0 行,第 1 列到第 3 列
array([1, 2, 3])
>>> a[:2, 2:] # 前 2 行,后 3 列
array([[2, 3, 4],
[7, 8, 9]])

形状操作

改变数组的形状

我们可以使用 numpy 提供的各种命令更改数组的形状,其中 reshaperesize 较为常用,值得注意的是,reshape 产生一个新的数组,不改变原有数组的形状,而 resize 就地更改数组的形状和大小。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>>> a = np.floor(10*np.random.random((3,4)))
>>> a
array([[0., 5., 1., 4.],
[4., 5., 0., 2.],
[0., 5., 6., 2.]])
>>> a.reshape(6,2)
array([[0., 5.],
[1., 4.],
[4., 5.],
[0., 2.],
[0., 5.],
[6., 2.]])
>>> a.ravel()
array([0., 5., 1., 4., 4., 5., 0., 2., 0., 5., 6., 2.])

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

下面是一些具体的说明

方法 描述
reshape() 返回包含具有新形状的相同数据的数组
resize() 就地更改数组的形状和大小
ravel() 返回一个扁平的数组

将不同数组堆叠在一起

我们可以使用 vstackhstack 函数将几个数组进行垂直或者水平方向的拼接

1
2
3
4
5
6
7
8
9
10
>>> a = np.array([[1, 2, 3], [4, 5, 6]])
>>> b = np.arange(10, 16).reshape(2,3)
>>> np.vstack((a,b))
array([[ 1, 2, 3],
[ 4, 5, 6],
[10, 11, 12],
[13, 14, 15]])
>>> np.hstack((a,b))
array([[ 1, 2, 3, 10, 11, 12],
[ 4, 5, 6, 13, 14, 15]])

功能和方法概述

以下是按类别排序的一些有用的 NumPy 函数和方法名称的列表。有关完整列表,请参阅参考手册里的常用 API

参考资料