1、概述
因为搬家和结婚的事比较忙,好久没更新博客了,TensorFlow的学习进度到了人脸识别,但是,总感觉自己都没写多少代码,这样跟学习Linux只会ls和cd命令有何区别?所以,我打算,更深入的学习机器学习,毕竟深度学习的一些算法也是从机器学习中来的。学习TensorFlow的时候,经常用到Numpy库,当时也没去深入的学习这个库,现在就从这个库开始新的征程。
2、Numpy简介
NumPy是Python语言的一个扩充程序库。支持高级大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。Numpy内部解除了Python的PIL(全局解释器锁),运算效率极好,是大量机器学习框架的基础库!(引自简书)
Numpy内置函数的处理数据的速度是C语音级别的,所以,在实际应用中,应该尽量使用内置函数。
3、numpy.genfromtxt
Numpy.genfromtxt函数可以从TXT文本中取出数据并进行处理。用代码来说明吧。
新建文本文件hello.txt,里面只有一行,hello python 123。数据准备好了,代码如下,
import numpy as np
myData = np.genfromtxt('hello.txt')
print(type(myData))
print(myData)
运行结果如下,
<class 'numpy.ndarray'>
[ nan nan 123.]
可以看到,其返回的结果的数据类型为numpy.ndarray。而前面两个值为“nan”,第三个值为123,说明,genfromtxt函数默认处理的数据类型为float,而默认的分隔符为空格。那么,我们想让结果为[‘hello’ ‘python’ ‘123’]怎么做呢?代码如下,
import numpy as np
myData = np.genfromtxt('hello.txt', dtype=str)
print(type(myData))
print(myData)
运行结果为,
<class 'numpy.ndarray'>
['hello' 'python' '123']
如果将hello.txt的内容改为,
id,name,math,english
1,wilf,61,66
2,momo,100,99
运行结果为,
<class 'numpy.ndarray'>
['id,name,math,english' '1,wilf,61,66' '2,momo,100,99']
这不符合我们一般想要的数据形式,怎么办?genfromtxt函数可以指定分隔符,代码如下,
import numpy as np
myData = np.genfromtxt('hello.txt', dtype=str, delimiter=',')
print(type(myData))
print(myData)
运行结果为,
<class 'numpy.ndarray'>
[['id' 'name' 'math' 'english']
['1' 'wilf' '61' '66']
['2' 'momo' '100' '99']]
如果要处理数据的话,一般第一行的标题我们也不需要,应该将其去掉,代码如下,
import numpy as np
myData = np.genfromtxt('hello.txt', dtype=str, delimiter=',', skip_header=1)
print(type(myData))
print(myData)
print(myData[1, 1])
运行结果为,
<class 'numpy.ndarray'>
[['1' 'wilf' '61' '66']
['2' 'momo' '100' '99']]
momo
genfromtxt函数还有很多参数,用到再看咯。那怎么看呢?Linux想查c函数的用法时有个man的命令,Numpy也有类似的help函数,比如想查看genfromtxt函数的用法,运行如下代码即可,
import numpy as np
print(help(np.genfromtxt))
运行结果为,
这里会打印出每个参数的含义,以及一些使用示例。
4、numpy.array
如果想创建数组,可以使用numpy.array函数,代码如下,
import numpy as np
myarray = np.array([1, 2, 3, 4])
myarray1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
print(myarray)
print(myarray1)
运行结果,
[1 2 3 4]
[[1 2 3 4]
[5 6 7 8]]
还可以获取矩阵的某部分,代码如下,
import numpy as np
myarray1 = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print('-------------')
print('获取第2-3行')
print(myarray1[1:3])
print('-------------')
print('获取首行到第2行')
print(myarray1[:2])
print('-------------')
print('获取第2行到尾行')
print(myarray1[1:])
print('-------------')
print('获取首列到第2列')
print(myarray1[:,:2])
print('-------------')
print('获取第2-3行,第2-3列')
print(myarray1[1:3,1:3])
运行结果,
-------------
获取第2-3行
[[4 5 6]
[7 8 9]]
-------------
获取首行到第2行
[[1 2 3]
[4 5 6]]
-------------
获取第2行到尾行
[[4 5 6]
[7 8 9]]
-------------
获取首列到第2列
[[1 2]
[4 5]
[7 8]]
-------------
获取第2-3行,第2-3列
[[5 6]
[8 9]]
5、shape
numpy.shape是查看矩阵维度的,代码如下,
import numpy as np
myarray = np.array([1, 2, 3, 4, 5])
myarray1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
myarray2 = np.array([[[1, 2, 3, 4], [5, 6, 7, 8],[9, 0, 0, 0]],[[1, 2, 3, 4], [5, 6, 7, 8],[9, 0, 0, 0]]])
print(myarray.shape)
print(myarray1.shape)
print(myarray2.shape)
运行结果,
(5,)
(2, 4)
(2, 3, 4)
6、数据类型转换
假设一个矩阵里的数据的类型都是str型,我们想把它们全部转成float型,代码如下,
import numpy as np
myArray = np.array(['1', '2', '3'])
print('-----------------------')
print('输出数据类型:')
print(myArray.dtype)
print('-----------------------')
myArray = myArray.astype(float)
print('转换后的数据类型:')
print(myArray.dtype)
运行结果,
-----------------------
输出数据类型:
<U1
-----------------------
转换后的数据类型:
float64
7、输出最大值和最小值
还可以输出矩阵中的最大值和最小值,
import numpy as np
myArray = np.array([[1, 2, 3], [4, 5, 6]])
print('-----------------------')
print('输出最大值:')
print(myArray.max())
print('-----------------------')
print('输出最小值:')
print(myArray.min())
运行结果,
-----------------------
输出最大值:
6
-----------------------
输出最小值:
1
8、求和
如果需要求矩阵行的和或者列的和,代码如下,
import numpy as np
myArray = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print('-----------------------')
print('求行和:')
print(myArray.sum(axis=1))
print('-----------------------')
print('求列和:')
print(myArray.sum(axis=0))
运行结果,
-----------------------
求行和:
[ 6 15 24]
-----------------------
求列和:
[12 15 18]
9、reshape维度转换
Reshape函数可以转换矩阵的维度,上代码,
import numpy as np
myArray = np.arange(12)
print('-----------------------')
print('转换前:')
print(myArray)
print('-----------------------')
print('转换成3行4列的矩阵:')
print(myArray.reshape(3, 4))
print(myArray.reshape(3, 4).shape)
print('-----------------------')
print('转换成4行3列的矩阵:')
print(myArray.reshape(4, 3))
print(myArray.reshape(4, 3).shape)
运行结果,
-----------------------
转换前:
[ 0 1 2 3 4 5 6 7 8 9 10 11]
-----------------------
转换成3行4列的矩阵:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
(3, 4)
-----------------------
转换成4行3列的矩阵:
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
(4, 3)
10、初始化矩阵
初始化一个值都是0的矩阵,代码如下,
import numpy as np
print(np.zeros((2, 3)))
运行结果,
[[0. 0. 0.]
- 0. 0.]]
初始化一个值都是1的矩阵,代码如下,
import numpy as np
print(np.ones((2, 3)))
运行结果,
[[1. 1. 1.]
- 1. 1.]]
初始化一个值是随机数的矩阵,代码如下,
import numpy as np
print(np.random.random((2, 3)))
运行结果,
[[0.08325535 0.09373238 0.55359789]
[0.8212977 0.46203935 0.31433286]]
如果想初始化值为以2递增的向量,怎么办呢?代码如下,
import numpy as np
print(np.arange(0, 10, 2))
运行结果,
[0 2 4 6 8]
如果想初始化值为一个区间的平均值,比如,10到100,分成10份,代码如下,
import numpy as np
print(np.linspace(10, 100, 10))
运行结果,
[ 10. 20. 30. 40. 50. 60. 70. 80. 90. 100.]
10、运算
直接上代码,
import numpy as np
a = np.array([5, 10, 15, 20])
b = np.arange(4)
c = np.array([[1, 2, 3], [4, 5, 6]])
d = np.array([[7, 8], [9, 10], [11, 12]])
e = np.array([[7, 8, 9], [10, 11, 12]])
print('-----------------------')
print('求矩阵相减:')
print(a - b)
print('-----------------------')
print('求矩阵减一个固定值:')
print(a - 2)
print('-----------------------')
print('求矩阵乘方:')
print(a ** 2)
print('-----------------------')
print('矩阵比较:')
print(a < 13)
print('-----------------------')
print('矩阵乘法:')
print(c * e)
print('-----------------------')
print('矩阵点乘:')
print(c.dot(d))
print('或者')
print(np.dot(c, d))
运行结果,
-----------------------
求矩阵相减:
[ 5 9 13 17]
-----------------------
求矩阵减一个固定值:
[ 3 8 13 18]
-----------------------
求矩阵乘方:
[ 25 100 225 400]
-----------------------
矩阵比较:
[ True True False False]
-----------------------
矩阵乘法:
[[ 7 16 27]
[40 55 72]]
-----------------------
矩阵点乘:
[[ 58 64]
[139 154]]
或者
[[ 58 64]
[139 154]]
12、其他操作
求e的指数,
import numpy as np
a = np.arange(3)
print(np.exp(a))
运行结果,
[1. 2.71828183 7.3890561 ]
求平方根,
import numpy as np
a = np.arange(3)
print(np.sqrt(a))
运行结果,
[0. 1. 1.41421356]
取整,
import numpy as np
print(np.floor(np.array([1.1, 2.2, 3.9])))
运行结果,
[1. 2. 3.]
调整矩阵结构,
import numpy as np
a = np.floor(10 * np.random.random((4, 3)))
print('-----------------------')
print('原结构:')
print(a)
print('-----------------------')
print('调整后的结构:')
a.resize((2, 6))
print(a)
运行结果,
-----------------------
原结构:
[[5. 9. 4.]
[1. 1. 9.]
[2. 7. 8.]
[3. 0. 7.]]
-----------------------
调整后的结构:
[[5. 9. 4. 1. 1. 9.]
[2. 7. 8. 3. 0. 7.]]
合并矩阵,
import numpy as np
a = np.floor(10 * np.random.random((2, 3)))
b = np.floor(10 * np.random.random((2, 3)))
print('-----------------------')
print('原矩阵:')
print('a:')
print(a)
print('b:')
print(b)
print('-----------------------')
print('横向合并:')
print(np.hstack((a, b)))
print('-----------------------')
print('纵向合并:')
print(np.vstack((a, b)))
运行结果,
-----------------------
原矩阵:
a:
[[2. 8. 2.]
[2. 7. 2.]]
b:
[[3. 1. 6.]
[5. 8. 6.]]
-----------------------
横向合并:
[[2. 8. 2. 3. 1. 6.]
[2. 7. 2. 5. 8. 6.]]
-----------------------
纵向合并:
[[2. 8. 2.]
[2. 7. 2.]
[3. 1. 6.]
[5. 8. 6.]]
拆分矩阵,
import numpy as np
a = np.floor(10 * np.random.random((2, 12)))
b = np.floor(10 * np.random.random((12, 2)))
print('-----------------------')
print('原矩阵:')
print('a:')
print(a)
print('b:')
print(b)
print('-----------------------')
print('横向拆分:')
print(np.hsplit(a, 3))
print('-----------------------')
print('指定横向拆分:')
print(np.hsplit(a, (2, 6)))
print('-----------------------')
print('纵向拆分:')
print(np.vsplit(b, 3))
运行结果,
-----------------------
原矩阵:
a:
[[7. 1. 1. 4. 8. 3. 9. 4. 2. 0. 3. 7.]
[2. 4. 3. 5. 0. 9. 0. 1. 4. 1. 0. 4.]]
b:
[[2. 7.]
[7. 4.]
[8. 8.]
[2. 0.]
[5. 0.]
[8. 5.]
[0. 5.]
[8. 7.]
[0. 5.]
[3. 3.]
[6. 6.]
[8. 4.]]
-----------------------
横向拆分:
[array([[7., 1., 1., 4.],
[2., 4., 3., 5.]]), array([[8., 3., 9., 4.],
[0., 9., 0., 1.]]), array([[2., 0., 3., 7.],
[4., 1., 0., 4.]])]
-----------------------
指定横向拆分:
[array([[7., 1.],
[2., 4.]]), array([[1., 4., 8., 3.],
[3., 5., 0., 9.]]), array([[9., 4., 2., 0., 3., 7.],
[0., 1., 4., 1., 0., 4.]])]
-----------------------
纵向拆分:
[array([[2., 7.],
[7., 4.],
[8., 8.],
[2., 0.]]), array([[5., 0.],
[8., 5.],
[0., 5.],
[8., 7.]]), array([[0., 5.],
[3., 3.],
[6., 6.],
[8., 4.]])]
复制矩阵,
import numpy as np
a = np.floor(10 * np.random.random((2, 2)))
print('-----------------------')
print('原矩阵:')
print('a:')
print(a)
print('-----------------------')
print('复制方法一:')
b = a.view()
print(b)
print('-----------------------')
print('复制方法二:')
b = a.copy()
print(b)
print('-----------------------')
print('复制方法三:')
b = a
print(b)
运行结果,
-----------------------
原矩阵:
a:
[[6. 1.]
[9. 8.]]
-----------------------
复制方法一:
[[6. 1.]
[9. 8.]]
-----------------------
复制方法二:
[[6. 1.]
[9. 8.]]
-----------------------
复制方法三:
[[6. 1.]
- 8.]]
这三种复制方法有区别吗?当然有啦,下面来分析,
import numpy as np
print('-----------------------')
a = np.arange(5)
print('复制方法一:')
b = a.view()
print('打印b矩阵:')
print(b)
print('分别打印id:')
print(id(a))
print(id(b))
print('修改b矩阵的某个值再打印a矩阵:')
b[1] = 123
print(a)
print('-----------------------')
a = np.arange(5)
print('复制方法二:')
b = a.copy()
print('打印b矩阵:')
print(b)
print('分别打印id:')
print(id(a))
print(id(b))
print('修改b矩阵的某个值再打印a矩阵:')
b[1] = 123
print(a)
print('-----------------------')
a = np.arange(5)
print('复制方法三:')
b = a
print('打印b矩阵:')
print(b)
print('分别打印id:')
print(id(a))
print(id(b))
print('修改b矩阵的某个值再打印a矩阵:')
b[1] = 123
print(a)
运行结果,
-----------------------
复制方法一:
打印b矩阵:
[0 1 2 3 4]
分别打印id:
140140380341152
140140380342912
修改b矩阵的某个值再打印a矩阵:
[ 0 123 2 3 4]
-----------------------
复制方法二:
打印b矩阵:
[0 1 2 3 4]
分别打印id:
140140165910736
140140380342992
修改b矩阵的某个值再打印a矩阵:
[0 1 2 3 4]
-----------------------
复制方法三:
打印b矩阵:
[0 1 2 3 4]
分别打印id:
140140380341152
140140380341152
修改b矩阵的某个值再打印a矩阵:
[ 0 123 2 3 4]
我们可以看到,用方法1和方法2复制矩阵,两个矩阵的id是不一样的,但是,方法一却共用数据,即不管是修改了a矩阵还是修改了b矩阵的数据,另一个矩阵的数据也随之改变。用方法二复制的矩阵,则两个矩阵完全独立。方法三其实不能算是复制,就是引用,两个矩阵的id和数据完全一样。
扩展矩阵,
import numpy as np
a = np.arange(4)
print('-----------------------')
print('原矩阵:')
print(a)
print('扩展以后的矩阵:')
print(np.tile(a, (3, 2)))
运行结果,
-----------------------
原矩阵:
[0 1 2 3]
扩展以后的矩阵:
[[0 1 2 3 0 1 2 3]
[0 1 2 3 0 1 2 3]
[0 1 2 3 0 1 2 3]]
排序,
import numpy as np
a = np.array([1, 5, 2, 9])
print('-----------------------')
print('原矩阵:')
print(a)
print('排序后的矩阵:')
print(np.sort(a, axis=0))
print('排序后的索引:')
print(np.argsort(a))
运行结果,
-----------------------
原矩阵:
[1 5 2 9]
排序后的矩阵:
[1 2 5 9]
排序后的索引:
[0 2 1 3]