import numpy as np #加载numpy包
np.set_printoptions(precision=4) #设置numpy输出为4位有效数
a=0;b=1;n=20 # n表示在[a,b]中生成n个点
x=np.linspace(a,b,n); # [a,b]中n个等差数据
x
array([0. , 0.0526, 0.1053, 0.1579, 0.2105, 0.2632, 0.3158, 0.3684, 0.4211, 0.4737, 0.5263, 0.5789, 0.6316, 0.6842, 0.7368, 0.7895, 0.8421, 0.8947, 0.9474, 1. ])
y=np.ones(n)/(b-a);y # y=1/(b-a)
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
import matplotlib.pyplot as plt
plt.plot(x,y);plt.ylim(0,1.5);plt.stem(x,y);
np.random.rand(1) #生成[0,1]上的一个随机实数:random.uniform(0,1)
array([0.5095])
np.random.seed(123) #设置种子数seed可重复结果,可任意设置
R=np.random.rand(10);R[:10] #[0,1]上的1000个随机数=np.random.uniform(0,1,1000)
array([0.6965, 0.2861, 0.2269, 0.5513, 0.7195, 0.4231, 0.9808, 0.6848, 0.4809, 0.3921])
plt.plot(R,'.');
from numpy import arange,exp #arange类似linspace函数
from math import sqrt,pi
x=arange(-4,4,0.1) #x为-4到4上间距为0.1的数
y=1/sqrt(2*pi)*exp(-x**2/2);
plt.plot(x,y);
import scipy.stats as st #加载统计方法包
p_z=st.norm.pdf(-2);p_z #p(z)=1/sqrt(2*pi)*exp(-z**2/2);
0.05399096651318806
za=st.norm.ppf(0.95);za #单侧
1.6448536269514722
[st.norm.ppf(0.025),st.norm.ppf(0.975)] #双侧
[-1.9599639845400545, 1.959963984540054]
p=st.norm.cdf(1.645);p #标准正态分布下的面积:p=P(z≤1.645)的累积概率
0.9500150944608786
#标准正态曲线下[a,b]上计算概率的面积图
import scipy.stats as st #加载统计方法包
def norm_p(a,b):
x=np.arange(-4,4,0.1)
y=st.norm.pdf(x)
x1=x[(a<=x) & (x<=b)];x1
y1=y[(a<=x) & (x<=b)];y1
p=st.norm.cdf(b)-st.norm.cdf(a);
print(" N(0,1)分布: [%3.2f,%3.2f] p=%5.4f"%(a,b,p))
plt.plot(x,y);#plt.text(-0.7,0.2,"p=%5.4f"%p,fontsize=15);
plt.hlines(0,-4,4); plt.vlines(x1,0,y1,colors='r');
norm_p(-4,-2) # p=P(z≤2)=0.27%
N(0,1)分布: [-4.00,-2.00] p=0.0227
norm_p(-2,2) # p=P(-2≤z≤2)=95.45%
N(0,1)分布: [-2.00,2.00] p=0.9545
norm_p(-1.96,1.96) # p=P(-1.96≤z≤1.96)=95%
N(0,1)分布: [-1.96,1.96] p=0.9500
np.random.normal(0,1,5) #生成 5 个标准正态分布随机数
array([ 1.2659, -0.8667, -0.6789, -0.0947, 1.4914])
#随机产生1000个标准正态分布随机数,作其概率直方图,然后再添加正态分布的密度函数线。
#np.random.seed(123) #设置种子数seed可使结果可重复
z1=np.random.normal(0,1,1000) #1000个标准正态分布随机数N(0,1)
z1[:20]
array([-0.6389, -0.444 , -0.4344, 2.2059, 2.1868, 1.0041, 0.3862, 0.7374, 1.4907, -0.9358, 1.1758, -1.2539, -0.6378, 0.9071, -1.4287, -0.1401, -0.8618, -0.2556, -2.7986, -1.7715])
plt.hist(z1); #可设定分段数bins, plt.hist(z1,bins=30)
np.random.seed(456) #设置种子seed可重复结果
z2=np.random.normal(0,1,1000)
plt.hist(z2);#plt.ylim=[0,400];
plt.hist(z1); plt.hist(z2); #做在一张图上
#一页绘制2个正态分布随机图
plt.subplot(121);plt.hist(z1);
plt.subplot(122);plt.hist(z2);
import pandas as pd
z12=pd.DataFrame({'z1':z1,'z2':z2}); z12 #构建数据框
z1 | z2 | |
---|---|---|
0 | -0.638902 | -0.668129 |
1 | -0.443982 | -0.498210 |
2 | -0.434351 | 0.618576 |
3 | 2.205930 | 0.568692 |
4 | 2.186786 | 1.350509 |
... | ... | ... |
995 | -0.807699 | 2.591205 |
996 | -1.276077 | -0.468390 |
997 | 0.553626 | 0.898201 |
998 | 0.553874 | -0.669727 |
999 | -0.691200 | 0.019731 |
1000 rows × 2 columns
z12.plot(kind='hist'); #根据数据框绘直方图
z12.plot(kind='hist',subplots=True,layout=(1,2));
z12.plot(kind='density',subplots=True,layout=(1,2)); #模拟正态分布曲线
np.random.seed(12) #设置种子数seed可重复结果
X=np.random.normal(170,10,100); X.round(1)
array([174.7, 163.2, 172.4, 153. , 177.5, 154.7, 170.1, 168.8, 161.9, 198.7, 164. , 174.7, 181. , 157.8, 183.4, 168.8, 180.1, 160.9, 159.7, 182.1, 175. , 171.4, 176.4, 175.3, 158.5, 147.9, 153.2, 152.1, 147.8, 163.5, 164.7, 169.6, 172.1, 166.2, 167.5, 170.7, 160. , 162.9, 170.4, 163.2, 164.3, 168.9, 183.4, 173.2, 166.6, 164.1, 168.9, 192.4, 138.5, 175.4, 172.3, 178.7, 158.5, 191.1, 180. , 169.5, 171.6, 162.8, 170.5, 168.6, 179.4, 173.6, 169.2, 176.8, 175.6, 172.2, 154.7, 180.3, 158.3, 159.9, 168.9, 175.1, 184.1, 153.1, 184.7, 186.4, 165.4, 168. , 164.3, 164. , 156.6, 153.1, 168. , 172.6, 188.3, 160. , 149.1, 171.5, 165.3, 173.6, 166. , 157.4, 163.1, 178. , 172.7, 160.3, 178.7, 155.5, 164.6, 172. ])
import warnings
warnings.filterwarnings("ignore") #忽略警告信息
import seaborn as sns
sns.distplot(X);
np.random.seed(15) #设置种子数seed可重复结果
Y=np.random.lognormal(0,1,1000); Y[:10]
array([0.7317, 1.4039, 0.8556, 0.6054, 1.2656, 0.1714, 0.3343, 0.337 , 0.737 , 0.6227])
sns.distplot(Y);
Z=np.log(Y) # Z=log(Y)
sns.distplot(Z);
import scipy.stats as st #加载科学计算包scipy的统计功能
st.probplot(X,plot=plt);
st.probplot(Y,plot=plt);
st.probplot(Z, plot=plt);
np.random.randint(0,2,100) #[0,1]上的10个随机整数
array([0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0])
np.random.randint(1,101,10) #[1,100]上的10个随机整数数组
array([32, 86, 52, 60, 20, 14, 3, 28, 31, 75])
np.random.seed(15) #结果可重复
np.random.randint(1,101,10)
array([73, 13, 6, 1, 29, 28, 72, 76, 86, 48])
import pandas as pd
pd.set_option('display.max_rows', 10)
BSdata=pd.read_excel('DaPy_data.xlsx','BSdata'); #读取学生数据
BSdata
学号 | 性别 | 身高 | 体重 | 支出 | 开设 | 课程 | 软件 | |
---|---|---|---|---|---|---|---|---|
0 | 1510248008 | 女 | 167 | 71 | 46.0 | 不清楚 | 都未学过 | No |
1 | 1510229019 | 男 | 171 | 68 | 10.4 | 有必要 | 概率统计 | Matlab |
2 | 1512108019 | 女 | 175 | 73 | 21.0 | 有必要 | 统计方法 | SPSS |
3 | 1512332010 | 男 | 169 | 74 | 4.9 | 有必要 | 编程技术 | Excel |
4 | 1512331015 | 男 | 154 | 55 | 25.9 | 有必要 | 都学习过 | Python |
... | ... | ... | ... | ... | ... | ... | ... | ... |
47 | 1538319004 | 男 | 175 | 68 | 44.4 | 不清楚 | 统计方法 | SAS |
48 | 1538254010 | 女 | 166 | 65 | 5.3 | 不清楚 | 编程技术 | Python |
49 | 1540294017 | 女 | 159 | 58 | 71.4 | 不清楚 | 都学习过 | SPSS |
50 | 1540365026 | 女 | 169 | 73 | 5.5 | 有必要 | 统计方法 | Excel |
51 | 1540388036 | 女 | 165 | 67 | 56.8 | 不必要 | 概率统计 | SAS |
52 rows × 8 columns
i=np.random.randint(1,53,6);i #抽取6名学生,取[1,52]上的6个整数
array([30, 18, 46, 32, 24, 33])
BSdata.iloc[i] #获取抽到的6名学生信息
学号 | 性别 | 身高 | 体重 | 支出 | 开设 | 课程 | 软件 | |
---|---|---|---|---|---|---|---|---|
30 | 1529365032 | 男 | 172 | 71 | 10.4 | 有必要 | 都学习过 | SPSS |
18 | 1524105026 | 女 | 163 | 65 | 69.4 | 有必要 | 编程技术 | Python |
46 | 1438120022 | 男 | 166 | 70 | 35.6 | 有必要 | 统计方法 | R |
32 | 1530243029 | 男 | 186 | 87 | 9.5 | 不必要 | 都未学过 | No |
24 | 1527173011 | 女 | 160 | 62 | 11.5 | 不必要 | 都学习过 | Matlab |
33 | 1531364037 | 女 | 171 | 69 | 7.3 | 有必要 | 都学习过 | Excel |
BSdata.sample(6) #直接抽取名学生及其信息
学号 | 性别 | 身高 | 体重 | 支出 | 开设 | 课程 | 软件 | |
---|---|---|---|---|---|---|---|---|
18 | 1524105026 | 女 | 163 | 65 | 69.4 | 有必要 | 编程技术 | Python |
33 | 1531364037 | 女 | 171 | 69 | 7.3 | 有必要 | 都学习过 | Excel |
45 | 1538399025 | 男 | 169 | 65 | 9.5 | 有必要 | 统计方法 | SAS |
28 | 1529314037 | 男 | 170 | 70 | 15.1 | 有必要 | 概率统计 | SAS |
30 | 1529365032 | 男 | 172 | 71 | 10.4 | 有必要 | 都学习过 | SPSS |
42 | 1537288004 | 女 | 173 | 70 | 19.1 | 不清楚 | 编程技术 | Python |
(1)正态均值的分布—正态分布
# 基于正态分布的中心极限定理模拟函数
import seaborn as sns
def norm_sim1(N=1000,n=10): # n为样本个数,N为模拟次数(即抽样次数)
xbar=np.zeros(N) # 产生放置样本均值的向量
for i in range(N): # 计算[0,1]上的标准正态随机数及均值
xbar[i]=np.random.normal(0,1,n).mean()
sns.distplot(xbar,bins=50) #plt.hist(xbar,bins=50)
print(pd.DataFrame(xbar).describe().T) #模拟结果的基本统计量
np.random.seed(1) #设置种子数seed使结果可重复
norm_sim1(10000,30) #根据默认值模拟
count mean std min 25% 50% 75% \ 0 10000.0 0.002303 0.184125 -0.751992 -0.121302 0.002808 0.128373 max 0 0.770898
np.random.seed(2) #设置种子数seed使结果可重复
norm_sim1(n=30,N=10000)
count mean std min 25% 50% 75% \ 0 10000.0 -0.003134 0.181091 -0.612653 -0.127927 -0.002509 0.120398 max 0 0.684151
# 基于非正态分布的中心极限定理模拟函数
def norm_sim2(N=1000,n=10):
xbar=np.zeros(N)
for i in range(N): #计算[0,1]上的均匀随机数及均值
xbar[i]=np.random.uniform(0,1,n).mean()
sns.distplot(xbar,bins=50)
print(pd.DataFrame(xbar).describe().T)
np.random.seed(3) #设置种子数seed使结果可重复
norm_sim2()
count mean std min 25% 50% 75% \ 0 1000.0 0.496785 0.090672 0.203241 0.436412 0.497801 0.560534 max 0 0.732275
np.random.seed(4) #设置种子数seed使结果可重复
norm_sim2(10000,30)
count mean std min 25% 50% 75% \ 0 10000.0 0.499467 0.052163 0.294711 0.463689 0.499249 0.534502 max 0 0.711937
x=np.arange(-4,4,0.1)
yn=st.norm.pdf(x,0,1); yt3=st.t.pdf(x,3); yt10=st.t.pdf(x,30)
plt.plot(x,yn,'r-',x,yt3,'b.',x,yt10,'g-.');
plt.legend(["N(0,1)","t(3)","t(10)"]);
import pandas as pd
BSdata=pd.read_excel('DaPy_data.xlsx','BSdata'); #读取学生数据
#BSdata
BSdata['身高'].mean()
168.51923076923077
BSdata['身高'].std()
8.01833776871194
f=BSdata['开设'].value_counts();
p=f/sum(f);p
有必要 0.557692 不清楚 0.230769 不必要 0.211538 Name: 开设, dtype: float64
#假定有 150 人接受调查,其中 42 人喜欢品牌 A,问喜欢 A 品牌的人占多大比例?
42/150
0.28
norm_p(-2,2)
N(0,1)分布: [-2.00,2.00] p=0.9545
import scipy.stats as st
def t_p(a,b,df=10): #t分布曲线下[a,b]上计算概率的面积图
x=np.arange(-4,4,0.1)
y=st.t.pdf(x,df)
x1=x[(a<=x) & (x<=b)];x1
y1=y[(a<=x) & (x<=b)];y1
p=st.t.cdf(b,df)-st.t.cdf(a,df);
print(" t("+str(df)+"): [%3.2f, %3.2f] p=%5.4f"%(a,b,p))
plt.plot(x,y);#plt.text(-0.7,0.2,"p=%5.4f"%p,fontsize=15);
plt.hlines(0,-4,4); plt.vlines(x1,0,y1,colors='r');
t_p(-2,2) #t:[-2,2], df=10
t(10): [-2.00, 2.00] p=0.9266
#基于原始数据的t分布均值和置信区间
def t_interval(x,b=0.95): #这里b为置信水平,通常取95%
a=1-b
n = len(x)
ta=st.t.ppf(1-a/2,n-1);ta
from math import sqrt
se=x.std()/sqrt(n)
return(x.mean()-ta*se, x.mean()+se*ta)
t_interval(BSdata['身高']) #身高均值的 95%的置信区间
(166.28691128155606, 170.7515502569055)
#单样本 t 检验函数进行均值的 t 检验
print("样本均值:",BSdata.身高.mean())
st.ttest_1samp(BSdata.身高,popmean = 166)
样本均值: 168.51923076923077
Ttest_1sampResult(statistic=2.2656106477907243, pvalue=0.02775093534857838)
st.ttest_1samp(BSdata.身高,popmean = 170)
Ttest_1sampResult(statistic=-1.3316948082433964, pvalue=0.188881956923451)
#定义单样本均值t检验图
def ttest_1plot(X,mu=0,k=0.1):
df=len(X)-1 #df=n-1
t1p=st.ttest_1samp(X, popmean = mu);
x=np.arange(-4,4,k); y=st.t.pdf(x,df)
t=abs(t1p[0]);p=t1p[1]
x1=x[x<=-t]; y1=y[x<=-t];
x2=x[x>=t]; y2=y[x>=t];
print(" 样本均值: \t%8.4f "%X.mean())
print(" 单样本t检验: t=%6.3f p=%6.4f"%(t,p))
t_interval=st.t.interval(0.95,len(X)-1,X.mean(),X.std())
print(" t置信区间:\t(%7.4f, %7.4f)"%(t_interval[0],t_interval[1]))
plt.plot(x,y); plt.hlines(0,-4,4);
plt.vlines(x1,0,y1,colors='r'); plt.vlines(x2,0,y2,colors='r');
plt.vlines(st.t.ppf(0.05/2,df),0,0.2,colors='b');
plt.vlines(-st.t.ppf(0.05/2,df),0,0.2,colors='b');
plt.text(-0.6,0.2,r"$\alpha$=%3.2f"%0.05,fontsize=15);
ttest_1plot(BSdata.身高,166) #总体均值为166时的推断图
样本均值: 168.5192 单样本t检验: t= 2.266 p=0.0278 t置信区间: (152.4217, 184.6167)
ttest_1plot(BSdata.身高,170) #总体均值为170时的推断图
样本均值: 168.5192 单样本t检验: t= 1.332 p=0.1889 t置信区间: (152.4217, 184.6167)