一。 numpy简介
n umPy 是一个 Python 包。 它代表 “Numeric Python”。 它是一个由多维数组对象和用于处理数组的例程集合组成的库。
Numeric,即 NumPy 的前身,是由 Jim Hugunin 开发的。 也开发了另一个包 Numarray ,它拥有一些额外的功能。 2005年,Travis Oliphant 通过将 Numarray 的功能集成到 Numeric 包中来创建 NumPy 包。 这个开源项目有很多贡献者。
numpy参考 :http://www.runoob.com/numpy/numpy-matplotlib.html
numpy官网 :http://www.numpy.org/
二。numpy常用操作
1.numpy创建ndarray
NumPy 数组的维数称为秩(rank),一维数组的秩为 1,二维数组的秩为 2,以此类推。
在 NumPy中,每一个线性的数组称为是一个轴(axis),也就是维度(dimensions)。比如说,二维数组相当于是两个一维数组,其中第一个一维数组中每个元素又是一个一维数组。所以一维数组就是 NumPy 中的轴(axis),第一个轴相当于是底层数组,第二个轴是底层数组里的数组。而轴的数量——秩,就是数组的维数。
很多时候可以声明 axis。axis=0,表示沿着第 0 轴进行操作,即对每一列进行操作;axis=1,表示沿着第1轴进行操作,即对每一行进行操作。
NumPy 的数组中比较重要 ndarray 对象属性有:
属性 | 说明 |
---|---|
ndarray.ndim | 秩,即轴的数量或维度的数量 |
ndarray.shape | 数组的维度,对于矩阵,n 行 m 列 |
ndarray.size | 数组元素的总个数,相当于 .shape 中 n*m 的值 |
ndarray.dtype | ndarray 对象的元素类型 |
ndarray.itemsize | ndarray 对象中每个元素的大小,以字节为单位 |
ndarray.flags | ndarray 对象的内存信息 |
ndarray.real | ndarray元素的实部 |
ndarray.image | ndarray 元素的虚部 |
ndarray.data | 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。 |
可以通过创建一个数组来获得他的属性
p=np.array([[1,2],[3,4]])
print(p.dtype)
print(p.shape)
打印结果:
int32
(2, 2)
关于他的创建方式非常多
import numpy as np
#创建矩阵
a=np.array([[1,2],[3,4]]);
#创建一个 3*3矩阵 默认值都是1
po=np.ones((3,3));
print(po);
#创建一个 4*4矩阵 默认值都是0
po=np.zeros((4,4))
print(po);
#创建一个方形矩阵 对角线是1 其他值都是0
po=np.eye(4)
print(po);
#创建一个5*5矩阵 初始值全部是5
po=np.full((5,5),5)
print(po);
#创建一个一维向量 从 1-9 步长是1
po=np.arange(1,10,1);
po=np.array([n for n in range(1,10,1)]);#等价
print(po);
print(po)
#创建一个等差数列的向量 从1-100 产生20个元素(默认50个)
po=np.linspace(1,100,20);
print(po)
'''产生一个等比数列 1-100次幂中产生10个数的等比数列
第一个数:1.000000e+001 就等于1.000000乘以10的+001次幂,也就是10
第二个数:1.00000000e+012 就等于 1.000000 乘以10的+023次幂 也就是 10**12
'''
po=np.logspace(1,100,10);
print(po)
print(1.00000000e+001)
#建指定形状和dtype的未初始化数组。 它使用以下构造函数:
po=np.empty((2,3))
print(po);
'''
沿着轴线将数据设置成索引值
[[[0 0 0 0]
[1 1 1 1]
[2 2 2 2]] 水平
[[0 1 2 3]
[0 1 2 3]
[0 1 2 3]]] 垂直
'''
po=np.indices((3,4));
print(po);
2。np切片操作
np可以使用下标的方式来进行切片 截取 具体语法参考:
import numpy as np
p=np.array([n for n in range(1,10)]).reshape((3,3))
'''
[[1 2 3]
[4 5 6]
[7 8 9]]
'''
print(p);
'''
返回第1行
[1 2 3]
'''
print(p[0])
'''
返回第1行到第二行 但是不包括第二行 还是个二维数组
:表示当前维度 通过将由冒号分隔的切片参数(start:stop:step)直接提供给ndarray对象
,用于分割维度
[[1 2 3]]
'''
#表示一行到第二行 不包括第二行
print(p[0:1])
#表示从 第一行到第四行不包括4 每次跳 2步
print(p[0:3:2])
#返回第 1行 第2列的元素
print(p[0,2])
#返回第1行的第2-3个元素 都是包含开头不包含结尾
print(p[0,1:3])
#返回所有行和所有列
print(p[:,:])
#返回第二行和第三列所有元素
print(p[1:,2:])
# -1表示最后一行
print(p[-1])
# -表示最后一行和最后一列
print(p[-1,-1])
#按照条件截取
#找出所有大于5的
print(p[p>5])
#找出所有偶数
print(p[p%2==0])
#查找所有的数组 取反
a=np.array([1,2,np.nan,np.nan])
print(a[~np.isnan(a)])
3。矩阵的合并
可以通过np的某些方法水平或者垂直合并矩阵
import numpy as np
p=np.arange(1,10).reshape((3,3));
p1=np.array([[-1,4,6],
[-2,8,11],
[8,3,1]
]);
print(p);
print(p1);
#合并矩阵 默认是在水平方向合并
print(np.concatenate((p,p1)));
print(np.hstack((p,p1))) #水平合并
# 0表示1维水平方向 1表示二维方向上 也就是垂直方向
print(np.concatenate((p,p1),axis=1));
print(np.vstack((p,p1))) #垂直合并
4。矩阵的计算
乘法运算
这里只是演示乘法运算其他运算如 + 、* / % 幂,对数,三角运算等
参考http://www.runoob.com/numpy/numpy-mathematical-functions.html
import numpy as np
p=np.array([[-1,4],
[-2,8]
]);
p1=np.array([[4,6],
[3,1]
]);
#矩阵乘法是将各个位置的值相乘
p3=p*p1;
print(p3);
print(np.multiply(p,p1)) #等价于上面
#点乘法 是将行和列相乘
'''
第一行的任意数字和第一列的任意数字累加
-1*4+-4*3=8 最后在第一行
第一行的任意数字和第二列的任意数字累加
-1*6+4*1=-2 在第一行
接下来第二行和第一列和第二列点乘 放在第二列
'''
print(np.dot(p,p1));#两个数组的点积,即元素对应相乘。 dot通用所有数组
print(np.matmul(p,p1))#两个数组的矩阵积
p=np.array([1,2]);
p1=np.array([2,3]);
print(np.vdot(p,p1))#两个向量的点积 1*2+2*3=8
print(np.inner(p,p1))
矩阵转置
import numpy as np
p=np.array([[-1,4,5],
[-2,8,6]
]);
#将第一行转换成第一列 其他行转换其他列
p1=p.transpose();
print(p1);
print(p.T);#等价于上面
逆矩阵
设A是数域上的一个n阶矩阵,若在相同数域上存在另一个n阶矩阵B,使得: AB=BA=E ,则我们称B是A的逆矩阵,而A则被称为可逆矩阵。注:E为单位矩阵。
比如:
按照矩阵的乘法满足:
(同一个值)
故A,B互为逆矩阵。
#必须是方形矩阵才能求逆矩阵
a = np.array([[1,2],[4,5]])
print(np.linalg.inv(a))
5。矩阵数据筛选
矩阵除了之前分片的方式之外,还可以通过不同的方式来筛选数据 比如 最大值,最小值,平均值,方差,求和,排序等操作来获取需要的数据
import numpy as np
p=np.array([[-1,4],
[-2,8]
]);
############求最大最小值#############
#获取整个矩阵的最大值 8
print(np.max(p))
print(np.max(p,axis=1)) #获取当前维度的最大值 二维就是每一行的最大值
print(np.argmax(p)) #从1维角度找到最大值的下标 8 在第4个位置也就是3上
print(np.argmax(p,axis=1)) #从2维角度获取最大值的下标 就是坐标 (1,1)
#获取最小值 -2
print(np.min(p))
print(np.argmin(p)) #获取最小值的位置 和 argmax一样
############求平均值#############
p1=np.array([[4,6],
[3,1]
]);
print(np.mean(p1)) #4+6+3+1/4=3.5 也可以设置水平和垂直
print(np.mean(p1,axis=0)) #[3.5,3.5] 垂直
print(np.mean(p1,axis=1)) #[5,3] 水平
############方差#############
print(np.var(p1))
print(np.mean(abs(p1 - p1.mean())**2))
import numpy as np;
arr=np.array([1,2,3,100,55])
#var 方差即各项-均值的平方求和后再除以N ,表示数据离平均数据的距离,表示数据的离散程度
print(np.var(arr))
print(np.sum(np.abs(arr-np.mean(arr))**2)/len(arr))#等价代码
print(np.mean(abs(arr - arr.mean())**2)) #等价代码
#std:表示标准差,是var的平方根。
print(np.std(arr))
print(np.sqrt(np.var(arr)));
#cov:协方差 ,与var类似,但是除以(N-1)
print(np.cov(arr));
print(np.sum(np.abs(arr-np.mean(arr))**2)/(len(arr)-1))#等价代码
关于排序的方法
import numpy as np
#默认按照行排序
p=np.array([[-1,8],
[4,-2]
]);
print(np.sort(p))
#按照列排序
print(np.sort(p,axis=0))
#自定义对象数据类型 参考http://www.runoob.com/numpy/numpy-dtype.html 按照字段排序
mtype=np.dtype([('name','S'),('age',int)])
p=np.array([('zs',20),('ww',60),('zl',30)],dtype=mtype)
print(np.sort(p,order='age'))
p=np.array([3,1,2])
#argsort() 函数返回的是数组值从小到大的索引值。
print(np.argsort(p))
#逆序
print(np.sort(p)[::-1])
三。numpy图像配套库 matplotlib
Matplotlib 是 Python 的绘图库。 它可与 NumPy 一起使用,提供了一种有效的 MatLab 开源替代方案。 它也可以和图形工具包一起使用,如 PyQt 和 wxPython。
以下学习 参考自 http://www.runoob.com/numpy/numpy-matplotlib.html
官网 :https://matplotlib.org/
以下案例参考自 https://cuijiahua.com/blog/2017/11/ml_1_knn.html
数据集合,也就是训练样本集。这个数据集有两个特征:即打斗镜头数和接吻镜头数。
除此之外,我们也知道每个电影的所属类型,即分类标签
电影名称 | 打斗镜头 | 接吻镜头 | 电影类型 |
神雕侠侣 | 100 | 20 | 动作片 |
毒液:致命守护者 | 99 | 10 | 动作片 |
碟中谍6:全面瓦解 | 67 | 5 | 动作片 |
热情如火 | 40 | 125 | 动作片 |
泰坦尼克号 | 0 | 10 | 爱情片 |
倩女幽魂 | 10 | 20 | 爱情片 |
大话西游之月光宝盒 | 10 | 40 | 爱情片 |
烈火如歌 | 1 | 30 | 爱情片 |
代码(绘制是二维图 所以指定一个x和y坐标的数组):
arr=np.array([[100,200],[99,10],[67,5],[40,125],[0,10],[10,20],[10,40],[1,30]]);
tarr=np.array([1,1,1,0,0,0,0]); #1表示动作片 0表示爱情片
x=arr[:,:1].T[0]
y=arr[:,1:].T[0]
print(x)
print(y)
#设置字体
mp.rcParams['font.family']=['STFangsong']
mp.title("电影类型图")
mp.xlabel("打斗镜头")
mp.ylabel("接吻镜头")
#第三个参数 o表示使用 散点 r表示red红色
mp.plot(x,y,"or")
mp.show();
执行结果:
以下是k邻近算法的实现
#判断打斗镜头44 接吻镜头 12到底是哪种类型的片片了
ndata=[44,12]
#计算当前这个ndata的坐标和之前所有数据的坐标的距离 放在一个jl数组中
#距离计算公式是 欧氏距离 (x-x1)**2 +(y-y1)**2 开平方根
# jl中每个下标的数据 就是ndata和对应位置xy坐标的距离
jl=[np.sqrt((ndata[0]-i[0])**2+(ndata[0]-i[1])**2) for i in arr];
print("未排序的数据是",jl);
#对距离进行排序 然后获取排序后的下标
# 比如数组: [10,12,8]
# argsort升序 [2,0,1]
jlsort=np.argsort(jl);
print("排序的索引是",jlsort);
k=3;
print(jlsort[:k])
#获取指定k 前三个值最小下标的标签 也就是前三个距离最近的都是什么类型的电影
# 比如[1,1,0]
flaga=[tarr[t] for t in jlsort[:k]];
print(flaga)
#统计类型集合的哪个出现的次数 会得到一个字典
#[(1,2),(0,1)]
group=c.Counter(flaga);#注意导入 import collections as c;
#获取到个数排序(从大到小) 值最大的前1个
#[(1,2)] [0][0]获取到1 类型就是动作片罗
print(group.most_common(1)[0][0]);
#来个三目判断下 输出中文
result=("动作片" if group.most_common(1)[0][0]==1 else "爱情片");
print(result);