NumPy 安装

使用 pip 可以方便地安装 NumPy。

python -m pip install numpy

NumPy 概览

# 引入 NumPy 包,习惯上引入为 np,方便书写
import numpy as np

# 将一个列表转换为 NumPy 数组
a = np.array([[1,2,3],[4,5,6]])

# 打印数组
print(a)

# 打印数组的维度、形状和大小
print('number of dim:', a.ndim)
print('shape', a.shape)
print('size:', a.size)
[[1 2 3]
 [4 5 6]]
number of dim: 2
shape (2, 3)
size: 6

NumPy 创建 Array

从 Python 列表创建

使用 np.array 从 Python 列表创建 NumPy Array

a = np.array([6,67,7])
print(a)
[6 67  7]

指定数据类型

使用 dtype 属性指定 NumPy Array 元素的类型。
例如要制定类型为整数型,则可以使用 np.int,可以使用 np.int32 进一步指定其为 32 位整数型。
从下面程序的输出结果看到,若不指定位数,np.int 默认为 64 位。

a = np.array([6,67,7], dtype=np.int)
print(a.dtype)
a = np.array([6,67,7], dtype=np.int32)
print(a.dtype)
a = np.array([6,67,7], dtype=np.int64)
print(a.dtype)
int32
int32
int64

其他类型,例如 float 同理。

a = np.array([6,67,7], dtype=np.float)
print(a.dtype)
a = np.array([6,67,7], dtype=np.float32)
print(a.dtype)
a = np.array([6,67,7], dtype=np.float64)
print(a.dtype)
float64
float32
float64

创建一个二维数组

a = np.array([[6,67,7],[6,67,7]])
print(a)
[[6 67  7]
 [6 67  7]]

全零数组

使用 np.zeros() 创建全零数组,以 (x_dim,y_dim) 的形式指定维度。

a = np.zeros((6,7) )
print(a)
[[0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0.]]

全一数组

使用 np.ones() 创建全一数组

a = np.ones((6,7) )
print(a)
[[1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1.]]

空数组

使用 np.empty() 创建全零数组
要注意的是,空矩阵填充的是内存中当前存放的值,是随机的。

a = np.empty((6,7) )
print(a)
[[1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1.]]

随机数组

使用 np.random.random() 创建随机数组

a = np.random.random((2,4))
print(a)
[[0.68673006 0.75950035 0.59310212 0.02855161]
 [0.23618792 0.82036725 0.68761253 0.4201456]]

np.arange()

使用 np.arange(),三个参数分别指定开始值、终值和步长,创建一个等差数列一维数组(不包含终值)。

a = np.arange(67,73,1)
print(a)
[67 68 69 70 71 72]

np.linspace()

使用 np.linspace(),三个参数依次为开始值、终值和节点数,创建一个等差数列一维数组。可以通过 endpoint 参数指定是否包含终值,默认值为 True。

a = np.linspace(67,73,7)
print(a)
[67. 68. 69. 70. 71. 72. 73.]

Array.reshape()

使用 Array.reshape() 方法,重塑数组。

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

NumPy 基础运算

加减

直接使用 + - 符号完成数组加减

# 示例数据
a = np.array([10,20,30,40])
b = np.arange(4)
print('a:',a,'b:',b)

c = a-b
print('a-b:',c)

c = a+b
print('a+b:',c)
a: [10 20 30 40] b: [0 1 2 3]
a-b: [10 19 28 37]
a+b: [10 21 32 43]

幂次方

使用 ** 符号完成针对数组元素的单独幂次方。

# 示例数据
b = np.arange(4)
print('b:',b)

c = b**2
print('b^2:',c)
b: [0 1 2 3]
b^2: [0 1 4 9]

三角函数

使用 np.sin() np.cos() np.tan() 等完成三角函数计算

# 示例数据
a = np.array([10,20,30,40])
b = np.arange(4)
print('a:',a,'\nb:',b)

c = np.sin(a)
print('sin(a):',c)

c = np.cos(a)
print('cos(a):',c)

c = np.tan(a)
print('tan(a):',c)
a: [10 20 30 40]
b: [0 1 2 3]
sin(a): [-0.54402111  0.91294525 -0.98803162  0.74511316]
cos(a): [-0.83907153  0.40808206  0.15425145 -0.66693806]
tan(a): [ 0.64836083  2.23716094 -6.4053312  -1.11721493]

大小比较

# 示例数据
b = np.arange(4)
print('b:',b)

print(b<3)
b: [0 1 2 3]
[True  True  True False]

乘法

使用 * 实现逐个相乘,使用 np.dot 实现矩阵乘法,也可以 Array.dot()

a = np.array([[1,1],[1,0]])
b = np.arange(4).reshape((2,2))

print('a:\n',a)
print('b:\n',b)

# 逐个相乘
c = a*b
print('c:\n',c)

# 矩阵乘法
c_dot = np.dot(a,b)
print('c_dot\n',c_dot)

c_cot = a.dot(b) # 另一种形式
print('another c_dot:\n',c_dot)
a:
 [[1 1]
 [1 0]]
b:
 [[0 1]
 [2 3]]
c:
 [[0 1]
 [2 0]]
c_dot
 [[2 4]
 [0 1]]
another c_dot:
 [[2 4]
 [0 1]]

求和、求最大值、求最小值

使用 np.sum() 求数组和,使用 np.max() 寻找数组中的最大值,使用 np.min() 寻找数组中的最小值。
可以使用 axis 参数指定求和的维度,在二维数组中,axis=0 代表在列方向上求数值,axis=1 代表在行方向上求数值。

a = np.random.random((2,4))
print('a:',a)

a_sum = np.sum(a)
a_min = np.min(a)
a_max = np.max(a)

print('\na_sum:',a_sum,'\na_min:',a_min,'\na_max:',a_max)

a_sum_0 = np.sum(a,axis=0) # 列
a_sum_1 = np.sum(a,axis=1) # 行
print('\na_sum_0:',a_sum_0)
print('a_sum_1:',a_sum_1)
a: [[0.24204778 0.87497235 0.38096849 0.17361687]
 [0.94614194 0.97785151 0.88869463 0.41283545]]

a_sum: 4.897129017685974
a_min: 0.17361687468327414
a_max: 0.9778515067213707

a_sum_0: [1.18818972 1.85282386 1.26966312 0.58645233]
a_sum_1: [1.67160549 3.22552353]

求最大 / 最小值索引

使用 np.argmax() np.argmin() 来求得最大值和最小值的位置

# 示例数据
a = np.arange(14,2,-1).reshape((3,4))
print('a:',a)

argmin = np.argmin(a)
print('argmin:',argmin)

argmax = np.argmax(a)
print('argmax:',argmax)
a: [[14 13 12 11]
 [10  9  8  7]
 [6  5  4  3]]
argmin: 11
argmax: 0

求均值、中位数

使用 np.mean() 求数组均值,使用 np.median() 求数组中位数。这些函数同样支持 axis 参数。

# 示例数据
a = np.arange(14,2,-1).reshape((3,4))
print('a:',a)

mean = np.mean(a)
print('\nmean:',mean)
print('a.mean():',a.mean())

median = np.median(a)
print('\nmedian:',median)

mean_0 = np.mean(a, axis=0) # 列
mean_1 = np.mean(a, axis=1) # 行
print('\nmean_0:',mean_0)
print('mean_1:',mean_1)
a: [[14 13 12 11]
 [10  9  8  7]
 [6  5  4  3]]

mean: 8.5
a.mean(): 8.5

median: 8.5

mean_0: [10.  9.  8.  7.]
mean_1: [12.5  8.5  4.5]

求累加和(Cumulative Sum)

使用 np.cumsum() 求数组累加和

# 示例数据
a = np.arange(14,2,-1).reshape((3,4))
print('a:',a)

cumsum = np.cumsum(a)
print('cumsum:',cumsum)
a: [[14 13 12 11]
 [10  9  8  7]
 [6  5  4  3]]
cumsum: [14  27  39  50  60  69  77  84  90  95  99 102]

求间差

使用 np.diff() 求间差

# 示例数据
a = np.arange(14,2,-1).reshape((3,4))
print('a:',a)

diff = np.diff(a)
print('diff:',diff)
a: [[14 13 12 11]
 [10  9  8  7]
 [6  5  4  3]]
diff: [[-1 -1 -1]
 [-1 -1 -1]
 [-1 -1 -1]]

求非零索引

使用 np.nonzero() 输出非零数的索引

# 示例数据
a = np.arange(14,2,-1).reshape((3,4))
print('a:',a)

nonzero = np.nonzero(a)
print('nonzero:',nonzero) # 输出非零数的索引
a: [[14 13 12 11]
 [10  9  8  7]
 [6  5  4  3]]
nonzero: (array([0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2], dtype=int64), array([0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3], dtype=int64))

逐行排序

使用 np.sort() 对数组进行逐行排序

# 示例数据
a = np.arange(14,2,-1).reshape((3,4))
print('a:',a)

sort_a = np.sort(a)
print('sort_a:',sort_a) #逐行排序
a: [[14 13 12 11]
 [10  9  8  7]
 [6  5  4  3]]
sort_a: [[11 12 13 14]
 [7  8  9 10]
 [3  4  5  6]]

转置

使用 np.transpose() 进行转置操作。使用 Array.T 也可以获取转置矩阵值。

# 示例数据
a = np.arange(14,2,-1).reshape((3,4))
print('a:',a)

transpose = np.transpose(a)
print('transpose:',transpose)
print('a.T:',a.T)
a: [[14 13 12 11]
 [10  9  8  7]
 [6  5  4  3]]
transpose: [[14 10  6]
 [13  9  5]
 [12  8  4]
 [11  7  3]]
a.T: [[14 10  6]
 [13  9  5]
 [12  8  4]
 [11  7  3]]

np.clip()

使用 np.clip(a,l,h),可以将 a 数组中小于 l 的元素置为 l,大于 h 的元素置为 h

# 示例数据
a = np.arange(3,15).reshape((3,4)
print('a:',a)

clip = np.clip(a,5,9)
print('clip:',clip)
  File "<ipython-input-26-7905e4d8b1e1>", line 3
    print('a:',a)
        ^
SyntaxError: invalid syntax

NumPy 索引

请看下面的示例:

# 示例数据
a = np.arange(3,15).reshape((3,4))
print('a:',a)

print("\n 索引一行:")
print(a[2]) # 索引第三行

print("\n 索引一个元素:")
print(a[2][1]) # 索引第三行第二列的数字
print(a[2,1]) # 另一种方式


print("\n「:」的用法:")
print(a[2,:]) # 选中第三行
print(a[:,1]) # 选中第二列
print(a[2,0:2]) # 选中第三行,第 1 至 2 个元素

print("\n 遍历行:")
for row in a:
  print(row)

print("\n 遍历列:")
for column in a.T:
  print(column)

print("\n 遍历每一个元素:")
print(a.flatten())
for item in a.flat:
  print(item)
a: [[3  4  5  6]
 [7  8  9 10]
 [11 12 13 14]]

索引一行:
[11 12 13 14]

索引一个元素:
12
12

「:」的用法:
[11 12 13 14]
[4  8 12]
[11 12]

遍历行:
[3 4 5 6]
[7  8  9 10]
[11 12 13 14]

遍历列:
[3  7 11]
[4  8 12]
[5  9 13]
[6 10 14]

遍历每一个元素:
[3  4  5  6  7  8  9 10 11 12 13 14]
3
4
5
6
7
8
9
10
11
12
13
14

Numpy Array 的合并

# 示例数据
a = np.array([1,1,1])
b = np.array([2,2,2])

# 上下合并
print("上下合并:")
print(np.vstack((a,b)))

# 横向合并
print("\n 横向合并:")
print(np.hstack((a,b)))

# 行向新维度
print("\n 创建一个行方向的新维度:")
print(a[np.newaxis,:])

# 列向新维度
print("\n 创建一个列方向的新维度:")
print(a[:,np.newaxis])

# 通过控制 axis 参数,融合了 np.vstack() 和 np.hstack()
print("\nnp.concatenate():")
c = np.concatenate((a,b),axis=0)
print(c)
上下合并:
[[1 1 1]
 [2 2 2]]

横向合并:
[1 1 1 2 2 2]

创建一个行方向的新维度:
[[1 1 1]]

创建一个列方向的新维度:
[[1]
 [1]
 [1]]

np.concatenate():
[1 1 1 2 2 2]

NumPy Array 的分割

使用 np.split() 切割 NumPy Array。第一个参数为要切割的数组。第二个参数表示分割方法,可以填写一个常数 n 表示平均分割乘 n 块,也可以填写一个列表用于不均等分割。axis 参数用于控制分割方向。

# 示例数据
a = np.arange(3,15).reshape((3,4))
print('a:',a)

print("纵向均等:")
print(np.split(a,2,axis=1)) #在纵向将 a 均等分为两块
print("横向均等:")
print(np.split(a,3,axis=0)) #在横向将 a 均等分为三块
print("纵向不均等:")
print(np.split(a,[1,1,2],axis=1)) #在纵向不均等分割
a: [[3  4  5  6]
 [7  8  9 10]
 [11 12 13 14]]
纵向均等:
[array([[ 3,  4],
       [7,  8],
       [11, 12]]), array([[ 5,  6],
       [9, 10],
       [13, 14]])]
横向均等:
[array([[3, 4, 5, 6]]), array([[ 7,  8,  9, 10]]), array([[11, 12, 13, 14]])]
纵向不均等:
[array([[ 3],
       [7],
       [11]]), array([], shape=(3, 0), dtype=int32), array([[ 4],
       [8],
       [12]]), array([[ 5,  6],
       [9, 10],
       [13, 14]])]

axis 参数的理解:前面提到的 axis 通常是,0 表示行方向,1 表示列方向,与这里的纵向横向直观上不太贴合。可以这么理解:axis=0 就是要将「列」给切开,axis=1 就是要将「行」切开。

NumPy Array 的复制

浅复制

如果使用赋值符号 = 直接复制 NumPy Array,实际上是创建了一个引用,而不是复制了一份数组中的数值。改变原数组,复制的数组也会改变,改变复制的数组,原数组也会改变。

a = np.arange(4)
print(a)
# 浅复制
b = a

# 查看 a 和 b 是否完全等价
print(b is a)

# 改变原数组
a[0] = 67
print(a)
print(b)

# 改变复制的数组
b[3] = 73
print(a)
print(b)
[0 1 2 3]
True
[67  1  2  3]
[67  1  2  3]
[67  1  2 73]
[67  1  2 73]

深复制

使用 Array.copy() 进行深复制,通过深复制的数组,进行了复制但不关联,不会相互影响。

a = np.arange(4)
print(a)

# 深复制
b = a.copy()

a[0] = 67
print(a)
print(b)
[0 1 2 3]
[67  1  2  3]
[0 1 2 3]