python如何简便使用cumsum函数完成绘制累计概率分布图(CDF)
累积分布函数(Cumulative Distribution Function),又叫分布函数,是概率密度函数的积分,能完整描述一个实随机变量X的概率分布。在电子器件制造中常常用于描述器件失效分布,可以明显的表示出在特定数值下的器件概率分布占比;虽然有一些博文已经介绍了一些方法,但是我在调研和绘制时发现,大部分的博文中都用了复杂的for循环语句来实现(可能是因为我太笨,看不懂for循环),并且大部
累积分布函数(Cumulative Distribution Function),又叫分布函数,是概率密度函数的积分,能完整描述一个实随机变量X的概率分布。在电子器件制造中常常用于描述器件失效分布,可以明显的表示出在特定数值下的器件概率分布占比;
虽然有一些博文已经介绍了一些方法,但是我在调研和绘制时发现,大部分的博文中都用了复杂的for循环语句来实现(可能是因为我太笨,看不懂for循环),并且大部分都不是针对DataFrame来做累计概率分布的,都是做简单列表,在解决问题的过程中,我发现了自己认为更加简单,易用的代码实现方法,在这里与大家分享,希望对大家有所帮助;
首先,介绍解决问题的思路:
众所周知,累计概率分布就是对于可选变量由小到大排列后,各个变量的累计概率形成的,因此:
**1)将所要处理的数据的所有可能取值中的唯一值以及唯一值出现的频数得出来;
2)所有数据的总数我们需要知道,因为每个数据出现频数除以数据总数才能获得该数据的概率;
3)将数据列表从小到大排列,然后将每个数据出现的概率进行叠加,这里需要用到cumsum函数;
4)绘制累计分布图**
然后,就是具体的代码分组讲解:
1)将所要处理的数据的所有可能取值中的唯一值以及唯一值出现的频数得出来;
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
这里是需要用到的模块,在程序最开始先调用,就像做菜准备好调料一样;
紧接着是数据的读取,为了简便讲解,这里仅仅选用数据的一部分,所用的数据是长度为193的列表,格式为csv,因此,应用read_csv命令,
#读取待处理数据
data=pd.read_csv("c:\\Users\\dell\\Desktop\\1.csv",header=None)
以下是运行代码的终端显示
数据类型为只有一列的dataframe格式;
#获取数据的总数
denominator=len(data[0])
#将数据转换为Series
Data=pd.Series(data[0])
#利用value_counts方法进行分组频数计算
Fre=Data.value_counts()
#对获得的表格整体按照索引自小到大进行排序
Fre_sort=Fre.sort_index(axis=0,ascending=True)
得到的Fre_sort数据如下所示:
2)所有数据的总数我们需要知道,因为每个数据出现频数除以数据总数才能获得该数据的概率;
#重置表格索引
Fre_df=Fre_sort.reset_index()
#将频数转换成概率
Fre_df[0]=Fre_df[0]/denominator
#将列表列索引重命名
Fre_df.columns=['Rds','Fre']
得到的列表输出如下所示:
3)将数据列表从小到大排列,然后将每个数据出现的概率进行叠加,这里需要用到cumsum函数;
#利用cumsum函数进行概率的累加并按照顺序添加到表格中
Fre_df['cumsum']=np.cumsum(Fre_df['Fre'])
数据表格输出如下所示:
#创建画布
plot=plt.figure()
#只有一张图,也可以多张
ax1=plot.add_subplot(1,1,1)
#按照Rds列为横坐标,累计概率分布为纵坐标作图
ax1.plot(Fre_df['Rds'],Fre_df['cumsum'])
#图的标题
ax1.set_title("CDF")
#横轴名
ax1.set_xlabel("Rds")
#纵轴名
ax1.set_ylabel("P")
#横轴的界限
ax1.set_xlim(0.1,0.5)
#图片显示
plt.show()
4)绘制累计分布图
图片输出如下所示:
完整代码如下所示:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
data=[]
data=pd.read_csv("c:\\Users\\dell\\Desktop\\1.csv",header=None)
denominator=len(data[0])#分母数量
Data=pd.Series(data[0])#将数据转换为Series利用分组频数计算
Fre=Data.value_counts()
Fre_sort=Fre.sort_index(axis=0,ascending=True)
Fre_df=Fre_sort.reset_index()#将Series数据转换为DataFrame
Fre_df[0]=Fre_df[0]/denominator#转换成概率
Fre_df.columns=['Rds','Fre']
Fre_df['cumsum']=np.cumsum(Fre_df['Fre'])
plot=plt.figure()
ax1=plot.add_subplot(1,1,1)
ax1.plot(Fre_df['Rds'],Fre_df['cumsum'])
ax1.set_title("CDF")
ax1.set_xlabel("Rds")
ax1.set_ylabel("P")
ax1.set_xlim(0.1,0.5)
plt.show()
注意事项:
1)在需要对数据进行频数计算时,需要用到pd.Series的value_counts方法,但是read_csv的数据格式是pd.DataFrame,因此,需要通过pd.Series方法对dataframe中的data[0]列进行转换,即
Data=pd.Series(data[0])#将数据转换为Series利用分组频数计算
Fre=Data.value_counts()
2)在对Fre数据表格进行排序时,需要用到Series和DataFrame的sort_index函数,其中axis=0代表按照行索引进行排序,默认是升序,降序用ascending=False来限定,如果按照特定行或列,可以在by参数中进行陷定;
Fre=Data.value_counts()
Fre_sort=Fre.sort_index(axis=0,ascending=True)
3)cumsum函数特别适合于进行CDF图绘制,与for循环相比,效率应该更高;
Fre_df['cumsum']=np.cumsum(Fre_df['Fre'])
4)图片的横坐标界限需要细化,否则,由于里面的个别异常点导致图像的可视化程度降低,也可以通过布尔索引,将异常值去掉;
更多推荐
所有评论(0)