numpy(numerical python)是一个开源的 Python 科学计算库,支持大量的数组与矩阵运算,并为其提供了大量的数学函数。numpy 是用 C 语言开发的,比 Python 的自带数据结构 Tuple、List、Dictionary 和 Set 都要快。另外 numpy 是属于 Python 的扩展程序库,也即是第三方库,所以以前没有安装 numpy 库的小伙伴们需要先安装 numpy。由于 numpy 库是一个科学计算库,所以在本篇我们将采用 Anaconda 中自带的 jupyter notebook 来给小伙伴们演示 numpy 的各种方法。如果有不了解 Anaconda 的小伙伴,可以先了解一下:https://www.jianshu.com/p/68f0565c7036
首先定义一个二维列表 arr
(类型为List[List[int]]),然后通过 numpy 的 np.array
方法将 Python 列表 arr
转成 numpy 中的数组 arr1
(类型为ndarray):
In [1]: import numpy as np
arr = [[1,2,3],[2,3,4]]
arr1 = np.array(arr)
arr1
Out [1]: array([[1, 2, 3],
[2, 3, 4]])
接着我们调用 size
函数查看 arr1
元素的个数:
In [2]: print(arr1.size)
Out [2]: 6
然后我们可以通过 shape
函数查看 arr1
的形状:
In [3]: print(arr1.shape)
Out [3]: (2, 3)
我们可以将 List 转成 ndarray,并指定 ndarray 元素的类型为 int:
In [4]: a = np.array([2,42,11,3],dtype=np.int)
print(a.dtype)
Out [4]: int64
同样地,我们也可以指定 ndarray元素类型为 float:
In [5]: a = np.array([2,42,11,3],dtype=np.float)
print(a.dtype)
Out [5]: float64
我们可以通过 zeros
函数填充一个3行4列的矩阵:
In [6]: a = np.zeros((3,4))
print(a)
Out [6]: [[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
常用的还有使用 ones
函数填充矩阵:
In [7]: a = np.ones((3,2),dtype=int)
print(a)
Out [7]: [[1 1]
[1 1]
[1 1]]
使用 arange
函数生成一个10到20的数组,步长为2:
In [8]: a = np.arange(10,20,2)
print(a)
Out [8]: [10 12 14 16 18]
也可以使用 reshape
函数对 arange
生成的数组重新定义形状:
In [9]: a = np.arange(12).reshape((3,4)) # np.arange(12) 表示生成一个从0到11的数组,共12个值,步长默认为1
print(a)
Out [9]: [[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
通过 linspace
函数可以切分数据:
In [10]: a = np.linspace(1,10,5) #从1到10,切成5个段(区间)
print(a)
Out [10]: [ 1. 3.25 5.5 7.75 10. ]
对数组按照元素进行 加减乘除:
In [11]: a = np.array([10,20,30,40])
b = np.array([1,2,3,4])
c = np.arange(4) #不包括4,从0 到 3 共4个元素
print(a-b) #两个数组中每个元素相减
print(b+c) #两个数组中每个元素相加
print(b**2) #数组b的平方
print(a*b) # 两个数组相乘
Out [11]: [ 9 18 27 36]
[1 3 5 7]
[ 1 4 9 16]
[ 10 40 90 160]
random
函数可以生成0-1之间的随机数值:
In [12]: a = np.random.random((2,4)) #2行4列的随机数(0-1)之间
print(a)
Out [12]: [[0.97164977 0.14426644 0.36158434 0.17456143]
[0.04331342 0.18312231 0.2126627 0.17222228]]
我们可以通过 sum
函数、min
函数和 max
函数分别得到数组的各个元素的和,最小值和最大值:
In [13]: print(np.sum(a)) #a的元素之和
print(np.min(a)) #a的最小值
print(np.max(a)) #a的最大值
Out [13]: 2.2633826930383676
0.043313416357604995
0.9716497706841624
另外,如果声明了 axis
参数,可以对数组的行或者列进行统计:
In [14]: print(np.sum(a,axis=1)) # axis=1代表行
print(np.sum(a,axis=0)) # axis=0代表列
Out [14]: [1.65206198 0.61132071]
[1.01496319 0.32738875 0.57424704 0.34678372]
当然,也可以用 argmin
函数和 argmax
函数分别得到数组中最小值的索引和最大值的索引:
In [15]: print(np.argmin(a)) #该矩阵最小值的索引
print(np.argmax(a)) #该矩阵最大值的索引
Out [15]: 4
0
如果想输出数组中所有非0元素的角标,可以用 nonzero
函数:
In [16]: print(np.nonzero(a)) #输出所有非0元素的角标
Out [16]: (array([0, 0, 0, 0, 1, 1, 1, 1]), array([0, 1, 2, 3, 0, 1, 2, 3]))
注,第一个数组代表行号,第二个数组代表列号
arange
函数也能生成一个倒序数值的数组:
In [17]: a = np.arange(11,-1,-1).reshape((3,4)) #arange包括第一个值,不包括第二个值的区间,11- -1 是从11到0,-1代表递减
print(a)
Out [17]: [[11 10 9 8]
[ 7 6 5 4]
[ 3 2 1 0]]
可以用 sort
函数对矩阵的每一行独立排序:
In [18]: print(np.sort(a))
Out [18]: [[ 8 9 10 11]
[ 4 5 6 7]
[ 0 1 2 3]]
在一些机器学习算法中,我们常常需要对矩阵进行转置运算:
In [19]: print(np.transpose(a)) #矩阵a的转置
Out [19]: [[11 7 3]
[10 6 2]
[ 9 5 1]
[ 8 4 0]]
a.T
也同样可以得到矩阵 a 的转置:
In [20]: print(a.T)
Out [20]: [[11 7 3]
[10 6 2]
[ 9 5 1]
[ 8 4 0]]
用矩阵a的转置乘以矩阵a也是常见的运算:
In [21]: print((a.T).dot(a))
Out [21]: [[179 158 137 116]
[158 140 122 104]
[137 122 107 92]
[116 104 92 80]]
对训练数据预处理的时候,往往要对异常值进行特殊处理,例如,对于矩阵a,用数值9代替大于9的值,用5代替小于5的值:
In [22]: print(np.clip(a,5,9))
Out [22]: [[9 9 9 8]
[7 6 5 5]
[5 5 5 5]]
我们往往需要对矩阵中某一行或者某一列进行操作:
In [23]: print(a[2,:]) #相当于取二维数组中角标为2的一整行
print(a[:,1]) #相当于取二维数组中角标为1的一整列
Out [23]: [3 2 1 0]
[10 6 2]
迭代矩阵中的每一行:
In [24]: for row in a:
print(row)
Out [24]: [11 10 9 8]
[7 6 5 4]
[3 2 1 0]
迭代矩阵的每一列,可以借助矩阵的转置操作:
In [25]: for col in a.T:
print(col)
Out [25]: [11 7 3]
[10 6 2]
[9 5 1]
[8 4 0]
用迭代器遍历矩阵的每一个元素:
In [26]: for item in a.flat:
print(item)
Out [26]: 11
10
9
8
7
6
5
4
3
2
1
0
上下合并两个数组:
In [27]: a = np.array([1,1,1])
b = np.array([2,2,2])
print(np.vstack((a,b))) #vertical stack 上下合并,把a和b作为两个元素 (a,b)为Tuple
Out [27]: [[1 1 1]
[2 2 2]]
左右合并两个数组:
In [28]: print(np.hstack((a,b))) #horizontal stack 左右合并
Out [28]: [1 1 1 2 2 2]
在数组上新增一个轴,变成矩阵:
In [29]: print(a[:,np.newaxis]) #在列上新加一个轴
print(a[np.newaxis,:]) #在行上新加一个轴
Out [29]: [[1]
[1]
[1]]
[[1 1 1]]
我们可以通过新增加轴的方式将行向量转成列向量:
In [30]: a = np.array([1,1,1])[:,np.newaxis]
b = np.array([2,2,2])[:,np.newaxis]
a,b
Out [30]: (array([[1],
[1],
[1]]), array([[2],
[2],
[2]]))
hstack
函数和 concatenate
函数均能左右合并两个或多个列向量:
In [31]: print(np.hstack((a,b,b)))
print(np.concatenate((a,b,b),axis=1)) # axis表示左右合并
Out [31]: [[1 2 2]
[1 2 2]
[1 2 2]]
[[1 2 2]
[1 2 2]
[1 2 2]]
按照行的维度等量切割矩阵:
In [32]: a = np.arange(12).reshape((3,4))
print(a)
print(np.split(a,3,axis=0)) # 矩阵a有3行,可以按照行切割成3块,除不尽会报错
Out [32]: [[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
按照列的维度等量切割矩阵:
In [33]: print(np.split(a,2,axis=1)) #有4列,可以分成两块 ,除不尽 会报错
Out [33]: [array([[0, 1],
[4, 5],
[8, 9]]), array([[ 2, 3],
[ 6, 7],
[10, 11]])]
我们也可以按照需要不等量切割矩阵:
In [34]: print(np.split(a,[1,1,2],axis=1)) # 按照(1,1,2)的方式对矩阵a进行按照列的维度切割
Out [34]: [array([[0],
[4],
[8]]), array([], shape=(3, 0), dtype=int64), array([[1],
[5],
[9]]), array([[ 2, 3],
[ 6, 7],
[10, 11]])]
另一种切割的方法:
In [35]: print(np.vsplit(a,3)) #上下切分
print(np.hsplit(a,2)) #左右切分
Out [35]: [array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
[array([[0, 1],
[4, 5],
[8, 9]]), array([[ 2, 3],
[ 6, 7],
[10, 11]])]
本篇到这里就要结束了,以上就是我在工作学习中,用到的常见的 numpy 库方法,小伙伴们想了解更多的 Python 知识,可以关注我的简书哦!