本文主要是介绍Numpy Pandas Pyplot的基本使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Numpy
数组
创建数组
numpy中的数组叫array
import numpy as np
a = np.array([2,4,8,20,16,30])
#嵌套元组创建二维数组
b = np.array(((1,2,3,4,5),(6,7,8,9,10),(10,9,1,2,3),(4,5,6,8,9.0)))
创建数组的方法:
-
array根据给出的数据创建
-
arange 能够根据给出的范围构建数组
-
empty构建一个裸数组,数组内的数全部未知
-
linspace 创建等距离的数组
-
random 使用随机数创建数组
a=np.arange(4,dtype=float)#创建浮点型数组:[0. 1. 2. 3.]
b=np.arange(0,10,2,dtype=int) #创建整型数组:[0, 2, 4, 6, 8]
# 前两个参数是区间的左右端点(左闭右开),第三个参数2代表步长是2,dtype用来指定数组的数据类型
c=np.empty((2,3),int) #创建2×3的整型空矩阵
d=np.linspace(-1,2,5) #创建数组:[-1., -0.25, 0.5, 1.25, 2.]
# linspace(a,b,c) ,从区间[a,b]的等距离的c个数。
e=np.random.randint(0,3,(2,3)) #生成[0,3)上的2行3列的随机整数数组
常用的参数
a=np.random.randint(1,11,(3,5)) #生成[1,11 )区间上3行5列的随机整数数组
print("维数:",a.ndim); #维数:2
print("维度:",a.shape) #维度:(3,5)
print("元素总数:",a.size); #元素总数:15
print("类型:",a.dtype) #类型:int32
print("每个元素字节数:",a.itemsize) #字节数:4
维度和大小
#这里的shape表示的是数组有几行几列
a=np.array([1,2,3])
print("维度为:",a.shape) #维度为:(3,)
b=np.array([[1,2,3]])
print("维度为:",b.shape) #维度为:(1,3)
c=np.array([[1],[2],[3]])
print("维度为:",c.shape) #维度为:(3,1) 第一层有三个元素[1],[2],[3],接下来一层每个元素中只有一个元素1
## 因此 [[[1],[2],[3]],[[4],[5],[6]]] 的shape是(2,3,1)
索引
a = np.array([2,4,8,20,16,30])
b = np.array(((1,2,3,4,5),(6,7,8,9,10),(10,9,1,2,3),(4,5,6,8,9.0)))
#中括号中写几项(逗号分隔) 代表单独这几项。
print(a[[2,3,5]]) #一维数组索引,输出:[ 8 20 30]
#项的下标可以用负数,表示从末尾开始倒着算
print(a[[-1,-2,-3]]) #一维数组索引,输出:[30 16 20]
#用冒号则表示区间:
print(b[:,1]) #输出第2列所有元素:[2. 7. 9. 5.]
print(b[[2,3],1:4]) #输出第3、4行,第2、3、4列的元素
print(b[1:3,1:3]) #输出第2、3行,第2、3列的元素
条件索引
中括号中可以加入一些条件,如b>2, b > a ,~isnan(a) 等
a=array([[1, nan, 2], [4, nan, 3]])
b=a[~isnan(a)] #提取a中非nan的数
print("b=",b)
print("b中大于2的元素有:", b[b>2])
#需要注意的是,中括号中的条件不一定必须要跟数组本身有关,他只是通过条件筛选出了一些下标
c=array([1,2,3,4,5,6])
d=c-10 #d = [-9,-8,-7,-6,-5,-4]
print(d[c>2]) # 输出[-7,-6,-5,-4]print(np.where(a>10,-1,a)) #a中大于10的元素改为-1
print(np.where(a>10,-1,0)) #a中大于10的元素改为-1,否则为0
# where用来查找并修改数组中的一些内容,可以视为a[a>b]的升级版
整行的添加/删除
x = np.array([[1,2],[3,4],[5,6]])
x[2,0] = -1 #修改第3行、第1列元素为-1y=np.delete(x,2,axis=0) #删除数组的第3行
#y = [[1,2],[3,4]]z=np.delete(y,0, axis=1) #删除数组的第1列t1=np.append(x,[[7,8]],axis=0) #增加一行
t2=np.append(x,[[9],[10],[11]],axis=1) #增加一列
#axis指出了要沿数组的第几个轴来加入数据(从0开始)
行列重塑(变形)
a=np.arange(4).reshape(2,2) #生成数组[[0,1],[2,3]]
b=np.arange(4).reshape(2,2) #生成数组[[0,1],[2,3]]print(a.reshape(4,),'\n',a) #输出:[0 1 2 3]和[[0,1],[2,3]]
print(b.resize(4,),'\n',b) #输出:None和[0 1 2 3]
reshape()返回一个新的数组, 而resize是修改原数组
resize中的参数不能是负数,reshape中可以将参数设置为-1来表示自动计算。(如a.reshapge(2,-1)则表示共两行,程序自己去算要几列)
平铺
可以使用reshape(-1)
或者用专门的函数ravel和flatten
- ravel只是创建了一个原内容的试图,改变原数组会改变平铺后的内容
- flatten是生成了一份copy,和原数组断绝联系
#程序文件Pex2_11.py
import numpy as np
a=np.arange(4).reshape(2,2) #生成数组[[0,1],[2,3]]
b=np.arange(4).reshape(2,2) #生成数组[[0,1],[2,3]]
c=np.arange(4).reshape(2,2) #生成数组[[0,1],[2,3]]print(a.reshape(-1),'\n',a) #输出:[0 1 2 3]和[[0,1],[2,3]]
#reshape中加-1能平铺
print(b.ravel(),'\n',b) #输出:[0 1 2 3]和[[0,1],[2,3]]
# ravel 是平铺
print(c.flatten(),'\n',c) #输出:[0 1 2 3]和[[0,1],[2,3]]
#flatten也是平铺##ravel 和 flatten 这两个方法在功能上是类似的,都是将多维数组展平为一维数组。主要的区别在于它们的返回值类型和性能:## 返回值类型:ravel 方法返回的是一个视图(view),这意味着它不创建新的数据,
# 只是提供了一个指向原始数组的指针。而 flatten 方法返回的是一个副本(copy),
# 它会创建一个新的数组,并复制原始数组的数据。
###性能:由于 ravel 返回的是视图,因此它通常比 flatten 更快,因为它不需要复制数据。
# 但这也意味着 ravel 的结果与原始数组是紧密联系的,
# 如果原始数组被修改,那么使用 ravel 得到的一维数组也会相应地改变。
#### 总结一下,如果你需要一个与原始数组紧密关联的一维数组,并且不希望复制数据,那么可以使用 ravel。如果你需要一个完全独立的一维数组副本,那么可以使用 flatten
堆叠Stack
a=np.arange(4).reshape(2,2) #生成数组[[0,1],[2,3]]
b=np.arange(4,8).reshape(2,2) #生成数组[[4,5],[6,7]]
# 这里的stack是堆叠的意思
c1=np.vstack([a,b]) #垂直方向组合
c2=np.r_[a,b] #垂直方向组合
d1=np.hstack([a,b]) #水平方向组合
d2=np.c_[a,b] #水平方向组合
- vstack用来垂直方向堆叠
- hstack用来水平方向堆叠
拆分
a=np.arange(4).reshape(2,2) #构造2行2列的矩阵
## split 是分隔的意思
b=np.hsplit(a,2) #把a平均分成2个列数组
c=np.vsplit(a,2) #把a平均分成2个行数组
- vstack是垂直方向拆分(这里的方向是分隔后的这些数组的相对方向)
- hspilt是水平方向拆分
运算
数组的直接运算就等于数组内所有元素对应运算
a=np.arange(10,15); b=np.arange(5,10)
c=a+b; d=a*b #对应元素相加和相乘
## modf的功能是分割数据的整数部分和小数部分,[0]是小数,[1]是整数
e1=np.modf(a/b)[0] #对应元素相除的小数部分
e2=np.modf(a/b)[1] #对应元素相除的整数部分
modf能够区分元素的小数部分和整数部分,注意**[0]对用的是小数部分**
使用numpy对整个数组进行运算会比挨个进行运算要快很多
x=[i*0.01 for i in range(1000000)] #从0.01到10000.00
start=time.time() #从公元纪年开始计时,到当前的秒
for (i,t) in enumerate(x): x[i]=math.sin(t)
print("math.sin:", time.time()-start)
#使用math库求0.01到10000.00的所有的sin,每个都要求一下sin
y=np.array([i*0.01 for i in range(1000000)])
start=time.time()
y=np.sin(y)
print("numpy.sin:", time.time()-start)
#使用numpy库求0.01到10000.00的所有的sin,将这些数设置为一个array,然后求一下## 时间
#math.sin: 0.12394881248474121
#numpy.sin: 0.008762121200561523
如果对不同大小的数组进行运算,那么会先对这两个数组进行扩充(扩充时用零元素),再运算。
# A: [[ 0]
# [10]]
# B: [1 2 3]
#A+B:
# [[11 12 13]
# [12 13 14]
# [13 14 15]]
#A*B:
# [[10 20 30]
# [11 22 33]
# [12 24 36]]
#A/B:
# [[10. 5. 3.33333333]
# [11. 5.5 3.66666667]
# [12. 6. 4. ]]
文件IO
txt
a=np.arange(0,3,0.5).reshape(2,3) #生成2×3的数组
np.savetxt("Pdata2_18_1.txt", a) #缺省按照'%.18e'格式保存数值,以空格分隔
b=np.loadtxt("Pdata2_18_1.txt") #返回浮点型数组
print("b=",b)
np.savetxt("Pdata2_18_2.txt", a, fmt="%d", delimiter=",") #保存为整型数据,以逗号分隔
c=np.loadtxt("Pdata2_18_2.txt",delimiter=",") #读入的时候也需要指定逗号分隔
print("c=",c)
delimiter用来标注分隔元素的字符
genfromtxt (generate from txt,从txt文本中生成)
#读前6行前8列数据
a=np.genfromtxt("Pdata2_21.txt",max_rows=6, usecols=range(8))
b=np.genfromtxt("Pdata2_21.txt",dtype=str,max_rows=6,usecols=[8]) #读第9列数据
b=[float(v.rstrip('kg')) for (i,v) in enumerate(b)] #删除kg,并转换为浮点型数据
#enumerate用来将一个可迭代对象组合成索引序列
#rstrip是一个python内置函数,用来删掉头尾的制定字符串(默认删除空格)
c=np.genfromtxt("Pdata2_21.txt",skip_header=6) #读最后一行数据
print(a,'\n',b,'\n',c)
dtype可以指定元素的类型
npy和npz
和txt类似,只是用到的函数不同
a=np.arange(6).reshape(2,3)
np.save("Pdata2_23_1.npy",a)
b=np.load("Pdata2_23_1.npy")
print(b)
如果是npy后缀的数据文件,那么直接用load和save
c=np.arange(6,12).reshape(2,3)
d=np.sin(c)
#将数据保存为npz的格式
np.savez("Pdata2_23_2.npz",c,d)
e=np.load("Pdata2_23_2.npz")
f1=e["arr_0"] #提取第一个数组的数据
f2=e["arr_1"] #提取第二个数组的数据
## 用arr_0 arr_1 来表示第1,2个数组的数据
## 所以f1 = c , f2 = d
如果是npz格式的文件,那么保存的时候要用savez
文件常用的属性
f=open("Pdata2_12.txt","w")
print("Name of the file:",f.name) #文件的名字
print("Closed or not:",f.closed)# 文件是否关闭
print("Opening mode:",f.mode)#文件打开的属性
f.close()
Pandas
序列Series
import pandas as pd
import numpy as np
s1=pd.Series(np.array([10.5,20.5,30.5])) #由数组构造序列,默认索引从0开始
s2=pd.Series({"北京":10.5,"上海":20.5,"广东":30.5}) #由字典构造序列
s3= pd.Series([10.5,20.5,30.5],index=['b','c','d']) #给出行标签命名
print(s1); print("--------------"); print(s2)
print("--------------"); print(s3)
二维表格DataFrame
构建
a=np.arange(1,7).reshape(3,2) #使用numpy构建一个array数组并重塑为3行2列
df1=pd.DataFrame(a) # 直接通过a构建二维表格,这时行列的索引都是从0开始的自然数
df2=pd.DataFrame(a,index=['a','b','c'], columns=['x1','x2'])# 给出行索引(index)和列索引(columns)
df3=pd.DataFrame({'x1':a[:,0],'x2':a[:,1]})#也可以按照字典的方法来指出索引
print(df1); print("---------"); print(df2)
print("---------"); print(df3)
数据分析
使用describe()可以对表格进行数据分析
a = np.arange(1,9).reshape(-1,2)
b = pd.DataFrame(a)
print(b.describe())
读取文件
csv格式
读入文件
数据来源:公司人事记录
时间范围:2019.1.1~2019.6.30year,month,day,gender,name,income
2019,3,7,男,张三,6&000
#2019,5,2,男,李四,13&000
2019,2,1,女,王玲,8&000内部数据,不要外传!
2019年3月
a=pd.read_csv("Pdata2_32.txt",sep=',',parse_dates={'birthday':[0,1,2]},#parse_dates参数通过字典实现前三列的日期解析,并合并为新字段birthdayskiprows=2,skipfooter=2,comment='#',thousands='&',engine='python')#输出
# birthday gender name income
#0 2019-03-07 男 张三 6000
#1 2019-02-01 女 王玲 8000
- sep指出分隔符
- parse_dates将某些列解析为日期格式,并合并成新的字段birthday
- skiprows 跳过前几行
- skipfooter跳过最后几行
- comment设置注释符,从注释符开始,这行之后的文本都不会被读取
- thousands设置千位分隔符(这样当遇到数字和 ‘&’ 的组合时会合并为一个大数字
- engine=‘python’ 使用python引擎读取文件
excel格式
读取和写入Excel
a=pd.read_excel("Pdata2_33.xlsx",usecols=range(1,4)) #提取第1列到第4列的数据
b=a.values #提取其中的数据
#生成DataFrame类型数据
c=pd.DataFrame(b,index=np.arange(1,11),columns=["用户A","用户B","用户C"])
f=pd.ExcelWriter('Pdata2_34.xlsx') #创建文件对象
c.to_excel(f,"sheet1") #把c写入Excel文件
c.to_excel(f,"sheet2") #c再写入另一个表单中
f._save() #一定要保存, 并且保存的函数是_save()
截取数据(定位信息)
a=pd.read_excel("Pdata2_33.xlsx",usecols=range(1,4)) #提取第1列到第4列的数据
print(a)
b1=a.iloc[np.arange(6),[0,1]] ## index locate
#通过标号筛选数据,行选择[0:6],列选择[0,1]
b2=a.loc[np.arange(6),["用户A","用户B"]] ## locate
## 通过标签筛选数据,这里的arange不是0~5的序号,而是行标签(只不过行标签正好和标号对应)
Pyplot
图形参数设置
- xlabel, ylabel 设置横纵坐标轴的标签
- rc设置图形的默认属性
- xticks 设置横坐标显示的编号,内容,以及显示属性(倾斜程度等)
- 等等
柱形图bar
import numpy as np, pandas as pd
from matplotlib.pyplot import *
a=pd.read_excel("Pdata2_33.xlsx",usecols=range(1,4)) #提取第2列到第4列的数据
c=np.sum(a) #求每一列的和
ind=np.array([1,2,3])
width=0.2
rc('font',size=16) #配置图形默认属性, 设置全局字体大小为16
bar(ind,c,width) #绘制条形图,序号用ind,值用c ,宽度用width
ylabel("消费数据") # y轴的标识
xlabel("用户名") # x轴的标识
xticks(ind,['用户A','用户B','用户C'],rotation=20) #旋转20度 #每个柱下面的对应标签
rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
savefig('figure2_36.png',dpi=500) #保存图片为文件figure2_36.png,像素为500
show() # 显示这个图
散点图scatter
import numpy as np
from matplotlib.pyplot import *
x=np.array(range(8))
y='27.0 26.8 26.5 26.3 26.1 25.7 25.3 24.8' #数据是粘贴过来的
y=",".join(y.split()) #把空格替换成逗号
y=np.array(eval(y)) #数据之间加逗号太麻烦,我们用程序转换
scatter(x,y) # 创建以x和y为 横纵坐标的散点图
savefig('figure2_23.png',dpi=500); show()
折线图plot
一般用比较密集的折线图来绘制函数图形
import numpy as np
from matplotlib.pyplot import rc,plot,xlabel,savefig,ylabel,legend,show
x=np.linspace(0,2*np.pi,200)
y1=np.sin(x); y2=np.cos(pow(x,2))
rc('font',size=16); rc('text', usetex=True) #调用tex字库
plot(x,y1,'r',label='$sin(x)$',linewidth=2) #Latex格式显示公式
plot(x,y2,'b--',label='$cos(x^2)$')
xlabel('$x$'); ylabel('$y$',rotation=0) #设置x轴标签和y轴标签
savefig('figure2_38.png',dpi=500)
legend() #添加图例
show()
多窗口subplot
x=np.linspace(0,2*np.pi,200)
y1=np.sin(x); y2=np.cos(x); y3=np.sin(x*x)
rc('font',size=16); rc('text', usetex=True) #调用tex字库
ax1=subplot(2,2,1) #新建左上1号子窗口
ax1.plot(x,y1,'r',label='$sin(x)$') #画图
legend() #添加图例
ax2=subplot(2,2,2) #新建右上2号子窗口
ax2.plot(x,y2,'b--',label='$cos(x)$'); legend()
ax3=subplot(2,1,2) #新建两行、1列的下面子窗口
ax3.plot(x,y3,'k--',label='$sin(x^2)$'); legend();
savefig('figure2_39.png',dpi=500); show()
subplot中的三个参数含义为:
subplot(n , m , k)
将整个页面分为n行m列,选取第k个作为子窗口
3D折线图
先根据三元组生成一些点,然后连成线
from mpl_toolkits import mplot3d
import matplotlib.pyplot as plt
import numpy as np
ax=plt.axes(projection='3d') #设置三维图形模式,并生成一个axes对象
z=np.linspace(0, 100, 1000) # z轴为基准轴
plt.rc("text",usetex=True)
## 设置X Y Z轴标签
ax.set_xlabel("$ X Label$")
ax.set_ylabel("$ Y Label$")
ax.set_zlabel("$ Z Label$")
x=np.sin(z)*z; y=np.cos(z)*z # 根据z来算出x和y
ax.plot3D(x, y, z, 'k') # 3D的plot
## x y z表示三个坐标轴的数据, 'k'则表示颜色为黑色
plt.savefig('figure2_40.png',dpi=500); plt.show()
3D面图/线图
创建网格型数据
X,Y=np.meshgrid(x, y) # 生成网格型数据
#将X和Y变为二维数据
## 等价于下面的代码
X = x + x.reshape(-1,1) * 0
Y = y.reshape(-1,1) + y * 0
使用plot_subplot来生成面图, 并用cmap来设置颜色映射
plot_surface用来生成面图, plot_wireframe则生成线图
x=np.linspace(-6,6,30)
y=np.linspace(-6,6,30)
X,Y=np.meshgrid(x, y) # 生成网格型数据
Z= np.sin(np.sqrt(X ** 2 + Y ** 2)) # 根据X和Y来获得Z
# 第一个窗口在左边
ax1=plt.subplot(1,2,1,projection='3d')
ax1.plot_surface(X, Y, Z,cmap='viridis')# cmap设置颜色映射,也就是染色方案
ax1.set_xlabel('x'); ax1.set_ylabel('y'); ax1.set_zlabel('z')
#第二个窗口在右边
ax2=plt.subplot(1,2,2,projection='3d');
ax2.plot_wireframe(X, Y, Z,color='c')
ax2.set_xlabel('x'); ax2.set_ylabel('y'); ax2.set_zlabel('z')
plt.savefig('figure2_41.png',dpi=500); plt.show()
等高线contour
z=np.loadtxt("Pdata2_42.txt") #加载高程数据
x=np.arange(0,1500,100)
y=np.arange(1200,-10,-100)
contr=plt.contour(x,y,z); plt.clabel(contr) #画等高线并标注
plt.xlabel('$x$'); plt.ylabel('$y$',rotation=0)
plt.savefig('figure2_42_1.png',dpi=500)
plt.show()
clabel是等高线的标注。
z中的数据是一个13行15列的矩阵,表示了x和y组成的各个点的高度信息
二维向量图quiver
x=linspace(0,15,11); y=linspace(0,10,12)
x,y=meshgrid(x,y) #生成网格数据
v1=y*cos(x); v2=y*sin(x)
plt.quiver(x,y,v1,v2)
#x和y表示向量起点, v1 v2表示向量的方向
plt.savefig('figure2_43.png',dpi=500); plt.show()
饼图pie
a=pd.read_excel("Trade.xlsx")
a['year']=a.Date.dt.year #添加交易年份字段
## dt.year表示按日期分割,选中其中的年
a['month']=a.Date.dt.month #添加交易月份字段
## dt.month表示按日期分割,选中其中的月
rc('font',family='SimHei') #用来正常显示中文标签
ax1=subplot(2,3,1) #建立第一个子图窗口
Class_Counts=a.Order_Class[a.year==2012].value_counts()
Class_Percent=Class_Counts/Class_Counts.sum()
ax1.set_aspect(aspect='equal') #设置纵横轴比例相等
ax1.pie(Class_Percent,labels=Class_Percent.index,autopct="%.1f%%") #添加格式化的百分比显示
ax1.set_title("2012年各等级订单比例")
show()
这篇关于Numpy Pandas Pyplot的基本使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!