numpy是一个科学计算库,专门用于矩阵,可以代替matlab的一些矩阵操作与计算。本篇内容的原型为某站200集AI教程的学习所得,后来经过博主结合其他博客,深化学习,产生了本篇博文。
文章目录
- 环境介绍
- numpy的IO库
- numpy建立矩阵
- shape打印矩阵形状
- dtype打印矩阵里面元素的类型
- numpy索引读取数据
- numpy切片
- 对numpy.array中所有元素做整体操作
- bool值当索引
- 矩阵元素的与、或条件筛选
- 矩阵元素的类型转换
- 矩阵求极值
- 求和(按照行或者列)
- 指数计算/开平方根
- 初始化0矩阵和1矩阵
- 矩阵的操作
- reshape重置矩阵的形状
- 矩阵的横向纵向拼接
- 矩阵的横向纵向切割
- 关于矩阵复制
- 赋值符号
- 浅复制
- 深复制
- 排序和索引
- 最值
- 扩展
- 排序
- 总结
- 参考资料
环境介绍
整个博文是在anaconda平台上基于python3.7实现的。
numpy的IO库
numpy提供了下列的IO函数:
save():将ndarray对象保存为.npy文件,为二进制文件
load():从.npy文件中获取ndarray对象
savetxt():将ndarray对象保存为.txt文件
loadtxt():从.txt文件中获取ndarray对象
简单用代码实现一下:
# 案例1,模拟读取txt
```python
from io import StringIO
import numpy as np
s = StringIO(u"1,1.3,abcde")
data = np.genfromtxt(s, dtype=[('myint','i8'),('myfloat','f8'), ('mystring','S5')], delimiter=",")
data
输出:
array((1, 1.3, b’abcde’),dtype=[(‘myint’, ‘<i8’), (‘myfloat’, ‘<f8’), (‘mystring’, ‘S5’)])
#案例2 ,真实读取txt文件,txt文件要规范,比如换行规范+用,隔开。
import numpy
world_alcohol = numpy.genfromtxt("word_alcohol.txt", delimiter=",",dtype=str)
#上面一句话是:实例化一个numpy.genfromtxt的对象,第一参数传要读取的文件名,第二个是分割符(每一行看作一条数据,逗号区分每个数据的属性),最 #后一个读取后的数据类型。这是用numpy.genfromtxt读取txt文件内容的方法。如果实际类型是时间,可以读进来再转化。
print(type(world_alcohol)) # <class 'numpy.ndarray'>
print(world_alcohol) # 打印ndarray对象的内容
print(help(numpy.genfromtxt)) # help函数,解释参数函数的用法。
#案例3,读取txt中的数据,且按照对应的格式,读取出来是一个对象列表,也可以理解为是一个一维矩阵
import numpy as np
data = np.genfromtxt("word_alcohol.txt", dtype=[('myint','i8') ,('mystring1','S5'), ('mystring2','S5') ,('mystring3','S5'),('myfloat','f8')], delimiter=",",skip_header=1)
#data = np.genfromtxt("word_alcohol.txt", delimiter=",",dtype=str,skip_header=1)
print(data)
#print(help(np.genfromtxt))
打印输出:
array([(1986, b'Weste', b'Viet ', b'Wine', 0. ),
(1986, b'Ameri', b'Urugu', b'Other', 0.5)],
dtype=[('myint', '<i8'), ('mystring1', 'S5'), ('mystring2', 'S5'), ('mystring3', 'S5'), ('myfloat', '<f8')])
numpy建立矩阵
如何利用numpy框架建立一个矩阵。
vector = numpy.array([5, 10, 15, 20]) #使用numpy.array方法把一个list转化为一个向量或者叫一行矩阵。
matrix = numpy.array([[5, 10, 15], [20, 25, 30], [35, 40, 45]]) #使用numpy.array方法把多个list转化为一个矩阵。
print(vector)
print(matrix)
总结:所以写一维矩阵写一个中括号,写二维矩阵写二个中括号,写三维矩阵写三个中括号。
shape打印矩阵形状
vector = numpy.array([5, 10, 15, 20])
print(vector.shape) #vector.shape就是打印该矩阵的形状,即几维,几行几列。
matrix = numpy.array([[5, 10, 15], [20, 25, 30], [35, 40, 45]])
print(matrix.shape) #matrix.shape就是打印该矩阵的形状,即几维,几行几列。
一般XXX.shape用作调试程序用。可以直接输出。
输出:
(4,) # 一行四列
(3, 3) # 3行3列 2维
在numpy的矩阵中,不像是list,你想放什么就放什么,是有格式要求的。里面必须是相同的结构,
dtype打印矩阵里面元素的类型
构建numpy矩阵时,要求里面的元素都是一样的类型,如果已有的整型/字符型/浮点型,满足不了需要,可以在读取的时候定义读取单个数据的dtype。就好像上面的读取txt文档的例子,不过这种定义dtype的类型一般读出来就是一维矩阵,类似一个java中list。
numbers = numpy.array([1, 2, 3, 4])
print(numbers)
print(numbers.dtype)
输出:
[1 2 3 4]
int32
当上述代码修改成下面时:
numbers = numpy.array([1, 2, 3, 4.0])
print(numbers)
print(numbers.dtype)
输出:
[ 1. 2. 3. 4.]
float64
如果其中一个改成字符串,那么最终的类型就是都是字符串。因为矩阵里面的类型要一致这个规则的限制,如果矩阵里面元素的基本类型不统一,会自动转型为高级类型,转型顺序:int < float < string。
numpy索引读取数据
import numpy
world_alcohol = numpy.genfromtxt("world_alcohol.txt", delimiter=",", dtype="U75", skip_header=1)
print(world_alcohol)
uruguay_other_1986 = world_alcohol[1,4] #我们需要取的数据是第2行第5个,同list第一个数据索引值为0
third_country = world_alcohol[2,2] #这行我们需要取的数据是第3行第3个。
print(uruguay_other_1986)
print(third_country)
需要注意的是索引从0开始,用中括号读取,第一个数字是第一个维度,第n个数字是第n个维度。
输出:
0.5
Cte d’Ivoire
numpy切片
切片,是把已有的矩阵取出来一个区域,待操作的矩阵可以是一维的也可以是多维的。
切片的规则:顾头不顾腚,即包含起始位置,不包含结束位置。
1)向量的切片
vector = numpy.array([5, 10, 15, 20]) #建立一个向量
print(vector[0:3]) #向量与list的切片方式一致,顾头不顾尾。也就是取0-1-2位置的三个数字。
输出:
[ 5 10 15]
2)矩阵的单列或单行切片,技巧使用冒号表示所有行或者列,也就是说可以单独拿出来某一行或者某一列。
matrix = numpy.array([
[5, 10, 15],
[20, 25, 30],
[35, 40, 45]
]) #建立矩阵
print(matrix[:,1]) # :表示这一行或一列的所有元素。以“,”为间隔,隔开行和列的位置(这里要区分索引用分号控制下标)。如果在第一个位置为行,第二个位置为列。
输出:
[10 25 40]
3)矩阵的多列或多行切片,采用切片的规则,顾头不顾腚
matrix = numpy.array([
[5, 10, 15],
[20, 25, 30],
[35, 40, 45]
])
print(matrix[:,0:2]) #以","为间隔,隔开行和列的位置。":"表示所有元素。 截取所有行的0和1列,这是做的切片,顾头不顾尾
输出:
[[ 5 10]
[20 25]
[35 40]]
matrix = numpy.array([
[5, 10, 15],
[20, 25, 30],
[35, 40, 45]
])
print(matrix[1:3,0:2])
# 截取第1-2行,第0-1列
输出:
[[20 25]
[35 40]]
对numpy.array中所有元素做整体操作
对numpy.array整体的操作=对numpy.array每一个元素做相同的操作。用变量做大于小于等于的操作,就可以得出矩阵里每个元素比较结果的矩阵。
vector = numpy.array([5, 10, 15, 20])
print(vector == 10)
output:
[False True False False]
这一条定律对矩阵一样适用:
matrix = numpy.array([
[5, 10, 15],
[20, 25, 30],
[35, 40, 45]
])
print(matrix == 25)
output:
[[False False False]
[False True False]
[False False False]]
总结:可以把比较的结果设置成一个变量,这样就能取出对应的符合条件的值了。
bool值当索引
上面的例子我们筛选出了符合条件的数据,形成了一个筛选结果矩阵。但是如何把这些符合筛选条件的元素取出来。
可以用bool值当索引。
方法:把某个矩阵的对应布尔值矩阵作为索引传递给原矩阵,则会返回出bool值为真的元素
vector = numpy.array([5, 10, 15, 20])
equal_to_ten = (vector == 10)
print(equal_to_ten)
print(vector[equal_to_ten])
output:
[False True False False]
[10]
上述规律对矩阵一样适用: 定位列之后,拿出来那一行的写法
matrix = np.array([
[5, 10, 15],
[20, 25, 30],
[35, 40, 45]
])
second_column_25 = (matrix[:,1] == 25) #单独拿出第1列与25比较,找出等于25的值
print(second_column_25)
print(matrix[second_column_25, :]) #会选出为true的那一行,second_column_25是所在的行号,:是取出该行的所有列
output:
[False True False]
[[20 25 30]]
矩阵元素的与、或条件筛选
1)bool值表的与,,用“&”表示
vector = numpy.array([5, 10, 15, 20])
#即等于10 又等于 5
equal_to_ten_and_five = (vector == 10) & (vector == 5)
print(equal_to_ten_and_five)
output:
[False False False False]
2)bool值表的或,用“|”表示
vector = numpy.array([5, 10, 15, 20])
#等于10 或者 等于 5
equal_to_ten_and_five = (vector == 10) | (vector == 5)
print(equal_to_ten_and_five)
结果:
[True True False False]
矩阵元素的类型转换
字符串在符合规则的情况下,可以转换为int或者float类型。
vector = np.array(["11", "2", "3"])#元素为字符串类型
print(vector.dtype)#打印元素类型 python 3 需要括号
print(vector)
vector = vector.astype(float)#用astype()方法进行强制类型转换。
print (vector.dtype)
print (vector)
输出结果:
<U2 #数字代表字符串的长度,可以这么理解,unicode2
[‘11’ ‘2’ ‘3’]
float64
[11. 2. 3.]
矩阵求极值
获得矩阵的最大值,最小值。
vector = np.array([5, 10, 15, 20])
print(vector.min())#求矩阵中最小的元素
print(vector.max()) #求矩阵中最小的元素
#print(help(np.array))#想了解更多的方法或函数,打印相关帮助即可
求和(按照行或者列)
matrix = numpy.array([
[5, 10, 15],
[20, 25, 30],
[35, 40, 45]
])
matrix.sum(axis=1) #按行求和,参数axis=1
#output:array([ 30, 75, 120])
matrix.sum(axis=0) #按列求和,参数axis=0
#output:array([60, 75, 90])
指数计算/开平方根
B = np.arange(3)# 生成一个[0 1 2]的一维矩阵,3为结束项
print(B)
print (np.exp(B))#exp是以e为底数,B的每个元素分别作为指数进行计算,计算结果以矩阵的方式显示
print (np.sqrt(B))#sqrt是对B的每个元素分别开根号,计算结果以矩阵的方式显示
输出结果:
[0 1 2]
[1. 2.71828183 7.3890561 ]
[0. 1. 1.41421356]
初始化0矩阵和1矩阵
可以利用numpy提供的api快速初始化指定维度的0矩阵和1矩阵,也就是矩阵的元素是0或者1.
zero_array = np.zeros((3,4))
print(zero_array)
one_array = np.ones((3,4),dtype=int)
print(one_array)
输出0矩阵或者1矩阵。如下:
[[1 1 1 1]
[1 1 1 1]
[1 1 1 1]]
矩阵的操作
a = np.floor(10*np.random.random((3,4))) #np.random.random((3,4)) 是0到1之间的随机浮点数3行4列,*10让数据扩大10倍便于分辨,floor方法是向下取整又叫舍尾法近似。
print(a)
print("----")
print(a.ravel())#a.ravel() 方法是把一个二维矩阵拉伸成一个1维向量,顺序是先第1行从左到右,然后第2行从左到右,以此类推
print("----")
a.shape = (6, 2)#把矩阵a的形状设置为6行2列
print(a)
print("----")
print(a.T)#把a矩阵转置,即把原来的第一列变为新矩阵的第一行,第二列变为新矩阵的第二行,即原来的行变为列,原来的列变为行,依次类推。
代码的输出为:
reshape重置矩阵的形状
print("----")
#reshape(3,-1)方法是修改矩阵的形状,3是3行,-1这个数表示让计算机根据其他维度的数据.
#自动算出-1这个地方应该填写多少,并完成修改。矩阵的拼接:
print(a.reshape(3,-1))
代码的输出:
矩阵的横向纵向拼接
主要是np的两个常用函数hstack,vstack。
a = np.floor(10*np.random.random((2,2)))
b = np.floor(10*np.random.random((2,2)))
print("------")
print(a)
print("------")
print(b)
print("------")
print(np.hstack((a,b)))# hstack方法是矩阵横向拼接方法
print("------")
print(np.vstack((a,b)))# hstack方法是矩阵纵向拼接方法
print("------")
代码的输出为:
------
[[5. 5.]
[2. 5.]]
------
[[6. 4.]
[5. 7.]]
------
[[5. 5. 6. 4.]
[2. 5. 5. 7.]]
------
[[5. 5.]
[2. 5.]
[6. 4.]
[5. 7.]]
------
矩阵的横向纵向切割
矩阵的切分:
a = np.floor(10*np.random.random((2,12)))
print(a)
print("------")
print (np.hsplit(a,3))# hsplit函数是横向切割,传入两个参数,第一个参数是要被切割的矩阵,第二个是切成几份。
print("------")
print (np.hsplit(a,(3,4)))# hsplit还有一种用法,指定在某几个位置切。该例子中,第二个位置参数是一个元组形式,表示在位置3,4分别切一刀
print("-----分割线----")
a = np.floor(10*np.random.random((12,2)))
print(a)
print("------")
np.vsplit(a,3)# vsplit函数是纵向切割,传入两个参数,第一个参数是要被切割的矩阵,第二个是切成几份。也可以做指定位置切割:
代码输出:
[[2. 7. 2. 9. 8. 6. 5. 4. 9. 9. 6. 5.]
[3. 6. 3. 3. 6. 8. 0. 7. 6. 5. 0. 1.]]
------
[array([[2., 7., 2., 9.],
[3., 6., 3., 3.]]), array([[8., 6., 5., 4.],
[6., 8., 0., 7.]]), array([[9., 9., 6., 5.],
[6., 5., 0., 1.]])]
------
[array([[2., 7., 2.],
[3., 6., 3.]]), array([[9.],
[3.]]), array([[8., 6., 5., 4., 9., 9., 6., 5.],
[6., 8., 0., 7., 6., 5., 0., 1.]])]
-----分割线----
[[5. 4.]
[0. 1.]
[8. 2.]
[7. 0.]
[4. 4.]
[5. 0.]
[9. 7.]
[7. 1.]
[8. 4.]
[5. 8.]
[4. 3.]
[8. 4.]]
------
[array([[5., 4.],
[0., 1.],
[8., 2.],
[7., 0.]]), array([[4., 4.],
[5., 0.],
[9., 7.],
[7., 1.]]), array([[8., 4.],
[5., 8.],
[4., 3.],
[8., 4.]])]
关于矩阵复制
赋值符号
指向一样,数据共享,内存空间是一块,类似一个人有两个名字,这不是真的复制。
a = np.arange(12)#建立一个12个元素的向量,命名为a
b = a
print(b is a)#打印判断b是不是a的结果
b.shape = (3,4)#把一维向量b的形状转化成3行4列的而二维矩阵
print (a.shape)#打印a的形状
print (id(a))#打印a的id,id是某个变量在内存中生成时,被赋予的具有唯一性的内存标识
print (id(b))#打印b的id
打印输出:
True
(3, 4)
4834999312
4834999312
浅复制
指向不同,但数据共享。
c = a.view()# 矩阵的view方法是浅复制,即c和a指向不同,但又同时共享着数据
print(c is a)#打印c是不是a的结果
c.shape = (2,6)
print (a.shape)
c[0,4] = 1234#把矩阵c第1行第5列元素赋值为1234
print (a)
output:
False
(3, 4)
[[ 0 1 2 3]
[1234 5 6 7]
[ 8 9 10 11]]
由此得出,矩阵的view方法是浅复制,即c和a指向不同,但又同时共享着数据。
深复制
想要完全
d = a.copy() # 矩阵的copy方法是深复制,即d和a指向不同,数据不同
print(d is a)
d[0,0] = 9999
print(d)
print(a)
output:
False
[[9999 1 2 3]
[1234 5 6 7]
[ 8 9 10 11]]
[[ 0 1 2 3]
[1234 5 6 7]
[ 8 9 10 11]]
排序和索引
最值
data = np.sin(np.arange(20)).reshape(5,4) #随机创建一个矩阵
print(data)
print("----")
ind = data.argmax(axis=0)#矩阵的argmax方法是求每列或每行的最大值,axis=0这个参数指按列统计(结果是该列的第几行最大,方便后面拿出来),axis=1是按行统计。
print(ind)
print("----")
print(data.shape)
print(data.shape[1]) #取出来具体的列的数目
print(data.shape[0]) #取出来具体的行的数目
print("----")
data_max = data[ind, range(data.shape[1])]#把每列最大的元素取出来。 2行0列,0行1列,3行2列,1行3列
print(data_max)
range() 函数可创建一个整数列表,一般用在 for 循环中。
data.shape[1] 是列数 data.shape[0] 是行数
关于np.sin(array),是获得矩阵里元素的正弦值。相关的资料可以查看:https://www.runoob.com/numpy/numpy-mathematical-functions.html
扩展
a = np.arange(0, 40, 10) #随机建立一个矩阵,从0到40,step为10,遍历出0-10-20-30
print(a)
print("---")
b = np.tile(a, (3, 5)) # tile方法是矩阵拓展方法,第一参数是把a作为整体当做一个元素进行扩展,第二个参数是扩展成3行5列的矩阵。
print(b)
输出的结果:
[ 0 10 20 30]
---
[[ 0 10 20 30 0 10 20 30 0 10 20 30 0 10 20 30 0 10 20 30]
[ 0 10 20 30 0 10 20 30 0 10 20 30 0 10 20 30 0 10 20 30]
[ 0 10 20 30 0 10 20 30 0 10 20 30 0 10 20 30 0 10 20 30]]
排序
a = np.array([[4, 3, 5], [1, 2, 1]])
print(a)
print("----")
b = np.sort(a, axis=1)#按照行对矩阵a排序,默认是从小到大排序,把新矩阵赋值给b
print(b)
print("----")
a.sort(axis=1)# 这种调用方法和np.sort(a,axis=1)效果一样
a = np.array([4, 3, 1, 2])
j = np.argsort(a)# argsort方法是先对矩阵a排序,然后对应求出每个元素在原来矩阵a中的索引
print (j)
print (a[j]) #把这个索引传入原矩阵就可以得到排序后的新矩阵。
output:
[[4 3 5]
[1 2 1]]
----
[[3 4 5]
[1 1 2]]
----
[2 3 1 0]
[1 2 3 4]