贡献者: addis
我们这里使用 numpy
模块中的数组。numpy
是数值计算中一个常用的模块,主要用于处理各种数组(或矩阵)。numpy
提供的是 ndarray 对象,即 n 维数组对象。这里介绍另一种 import 的方式
import numpy as np
这相当于给 numpy.
指定一个更简单的名字 np.
,方便了使用。你也可以把 np
替换成其他名字。上文使用 math
模块时也可以使用
import math as m
要创建一个一维数组(或者叫做行矢量),如
a = np.array([1, 2, 3])
这个数组有三个元素,每个元素相当于一个独立的变量。要获取第 i
个元素的值,用 a[i]
,如
a[0]
注意索引 i
从 0 开始而不是 1。所以第一个元素索引为 0,第二个索引为 1 等等。
用 type(a)
查看矩阵类型为 numpy.ndarray
,用 a.dtype
查看矩阵元的数据类型为 int32
。要转换矩阵元类型用 b = a.astype(类型)
。
要特别注意 b = a
并不能真正复制 np
数组,b
只是 a
的别名而已。要真正复制,用:b = a.copy()
,b = np.array(a)
。
要转换为 list,用
a.tolist()
显示整个数组
print(a)
要获取数组的一部分
a[1:2]
注意:python 对数组部分索引获取的时候,不会获取索引范围的最后一个索引值,即上面这个命令只会得到 a[1]
的值为 2,而没有 a[2]
的值。
要间隔一个步长获取数组的一部分,可以使用
a = np.array([1,2,3,4,5,6,7,8])
a[1:6:2]
括号中的第三个参数表示步长,2 表示隔一个元素取一个元素,上述代码取出 a
中第 1 个(注意不是第 0 个),第 3 个,第 5 个值,返回结果为 2,4,6。
创建一个二维数组,如(默认是行主序)
b = np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]])
数组的形状可以通过其 shape
属性获得。也可以用 shape()
函数 例如
a.shape # 或 shape(a)
b.shape # 或 shape(b)
最终会得到返回值为 tuple
类型
(8,)
(3, 4)
注意到返回值都有一个小括号,说明返回值类型为一个元组类型。数组 a
的 shape 只有一个元素,因此它是一维数组。而数组 c
的 shape 有两个元素,因此它是二维数组,其中第 0 轴的长度为 3,第 1 轴的长度为 4。
另外注意 np.array([1,2])
的形状是 (2,)
,而 np.array([[1,2]])
的形状是 (1,2)
。对 numpy 数组用单索引 [i]
的效果和 list 一样。
修改数组的 shape 属性,在保持数组元素个数不变的情况下,改变数组每个轴的长度。下面的例子将数组 c
的 shape 改为 (4,3)
,注意从 (3,4)
改为 (4,3)
并不是对数组进行转置,而只是改变每个轴的大小,数组元素在内存中的位置并没有改变:
b.shape = 4,3
print(b)
返回
array([[ 1, 2, 3],
[ 4, 4, 5],
[ 6, 7, 7],
[ 8, 9, 10]])
这种操作会永久的改变原数组的 shape。当某个轴的元素为-1 时,将根据数组元素的个数自动计算此轴的长度,因此下面的程序将数组 b
的 shape 改为 (4,3)
:
c.shape = 4,-1
另外,通过 reshape 方法,可以创建一个改变了尺寸的新数组,原数组的 shape 保持不变。例如
d = b.reshape((4,3))
print(b)
print(d)
返回
array([[1, 2, 3, 4],
[4, 5, 6, 7],
[7, 8, 9, 10]])
array([[ 1, 2, 3],
[ 4, 4, 5],
[ 6, 7, 7],
[ 8, 9, 10]])
其实数组 b
和 d
其实共享数据存储内存区域,因此修改其中任意一个数组的元素也会同时修改另外一个数组的内容。例如,
b[0]=999
print(b)
print(d)
输出
array([[999, 2, 3, 4],
[4, 5, 6, 7],
[7, 8, 9, 10]])
array([[ 999, 2, 3],
[ 4, 4, 5],
[ 6, 7, 7],
[ 8, 9, 10]])
arange
函数通过指定开始值、终值和步长来创建一维数组,注意数组不包括终值:
np.arange(0,10,1)
array([ 0,1, 2, 3, 4, 5, 6, 7, 8, 9])
linspace
函数通过指定开始值、终值和元素个数来创建一维数组,可以通过 endpoint
关键字指定是否包括终值,默认是包括终值:
np.linspace(0,1,10)
array([0. , 0.11111111, 0.22222222, 0.33333333, 0.44444444,
0.55555556, 0.66666667, 0.77777778, 0.88888889, 1. ])
zeros
创建全 0 数组
np.zeros(3)
array([0., 0., 0.])
np.zeros((3,5))
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
另外,ones
和 eye
创建全 1 数组,对角元为 1 的数组,用法与 zeros
类似。
下面分别介绍对矩阵进行一些常见的操作处理,包括转置,拼接,翻转,内积,外积,计算本征值,行列式,逆矩阵,等等在 python 中的实现。
A = [1, 2, 3]
B = [[2, 1, 4],[2, 2, 3],[1, 1, 3]]
C = [4, 5, 6]
转置
np.transpose(B)
拼接
D = np.concatenate((A,C)) # Concatenate vectors
print(D)
[1 2 3 4 5 6]
左右或者上下翻转矩阵,字母 u, d, l, r
分别是 up,down, left,和 right 的缩写。
D = np.flipud(A)
print(D)
E = np.fliplr(B)
print(E)
输出
[3 2 1]
array([[4, 1, 2],
[3, 2, 2],
[3, 1, 1]])
内积(也叫点乘),外积(也叫张量积)
D = np.dot(A,C)
print(D)
D = np.outer(A,C) # Outer product
print(D)
输出
32
[[ 4 5 6]
[ 8 10 12]
[12 15 18]]
计算本征值,逆矩阵,行列式
D = np.linalg.eigvals(B)
print(D)
D = np.linalg.inv(B)
print(D)
D = np.linalg.det(B)
print(D)
随机数,例如产生 0-1 之间的随机数
D = np.random.rand(3,5)
print(D)
创建其他随机数方法类似,例如正态分布随机数用 np.random.randn
函数。
m1*m2
matmul(m1, m2)