最近一个小需求需要用到正态分布,顺便复习了下如何用python实现。
直接上代码:
import pandas as pd
import numpy as np
import matplotlib.pyplot as pl
from pylab import mpl
#下面两条是为了最后图上的汉字显示不会乱码
mpl.rcParams['font.sans-serif']=['Microsoft YaHei']
mpl.rcParams['axes.unicode_minus'] = False
#定义正太分布函数,
def normalfun(x, mu, sigma):
pdf = np.exp(-((x-mu)**2)/(2*sigma**2))/(sigma*np.sqrt(2*np.pi))
return pdf
if __name__ == "__main__":
#读取本地CSV数据集,注意保存时定义格式为utf-8
data = pd.read_csv('d:/go/ai/data1.csv')
#读取price列
price = data['price']
#读取weight列
weight = data['weight']
#获取元素个数
length = len(price)
#print("%s: %s" % ("length:",length))
#print(price)
#print(weight)
#计算加权均值
mean=np.average(price,weights=weight)
print("%s: %s" % ("mean:", mean))
#计算不加权均值
#mean2 = price.mean()
#print("%s: %s" % ("mean2:", mean2))
#计算方差
fangcha = np.var(price)
print("%s: %s" % ("fangcha:",fangcha))
#计算标准差
std = price.std()
print("%s: %s" % ("std:",std))
#计算顶点值
value = normalfun(mean,mean,std)
#计算y,调用normalfun
y = normalfun(x,mean,std)
figure = pl.figure()
#绘制正太分布曲线
pl.plot(x, y)
#添加注释,注意%.1f表示保存一位小数,%.3f表示保存三位小数
pl.annotate('(%.1f, %.3f)'%(mean, value),xytext=(mean , value),xy=(mean , value),xycoords='data',
arrowprops=dict(facecolor='red', shrink=0.05))
#绘制直方图
#pl.hist(price, bins=200,rwidth=1, density=True)
#计算置信区间为90%的边界值,其中-1.64485为NORMSINV(0.1/2),此处用的Excel函数NORMALSINV获取该值,后续研究下如何python实现
#min_value = mean + (-1.64485) * std / np.sqrt(length)
#max_value = mean - (-1.64485) * std / np.sqrt(length)
#print("%s: %s" % (min_value, max_value))
#添加垂直方向line,添加水平方向使用hlines
#pl.vlines(min_value, 0, 0.01, colors='r', linestyle="--")
#pl.text(0, min_value, min_value)
#pl.vlines(max_value, 0, 0.01, colors='r', linestyle="--")
#pl.text(0, max_value, max_value)
#添加title/坐标轴label
pl.title('价格正太分布')
pl.xlabel('sales')
pl.ylabel('probability ')
#保存图片
figure.savefig("d:/go/ai/normal.png")
#显示图片
pl.show()