import numpy as np import pandas as pd from pandas import Series,DataFrame import matplotlib.pyplot as plt tips=pd.read_csv('tips.csv') print(tips.describe()) ''' total_bill tip size count 244.000000 244.000000 244.000000 mean 19.785943 2.998279 2.569672 std 8.902412 1.383638 0.951100 min 3.070000 1.000000 1.000000 25% 13.347500 2.000000 2.000000 50% 17.795000 2.900000 2.000000 75% 24.127500 3.562500 3.000000 max 50.810000 10.000000 6.000000 describe默认只能统计数字 ''' print(tips[['sex','smoker','day','time']].describe()) ''' sex smoker day time count 244 244 244 244 unique 2 2 4 2 多少不同的值 top Male No Sat Dinner 多数 freq 157 151 87 176 对应top的频率 ''' print(tips['sex'].value_counts()) ''' Male 157 Female 87 Name: sex, dtype: int64 ''' print(tips['sex']) #按列名索引 print(tips[0:3]) #0,1,2行 print(tips.at[1,'sex']) #1行 sex列对应值 print(tips.iat[1,1]) #根据位置索引 print(tips.loc[:,['sex','size']]) #冒号表示所有行,后面表示sex和size两列 print(tips.iloc[0,2]) #iat只能找对应的一个值,iloc可以找一个区域 print(tips.iloc[0:4,2:4]) #找到区域 #DataFrame的合并 #按行合并 #必须保证列相同 tips1=tips[:100] tips2=tips[100:] tips12=pd.concat([tips1,tips2]) #按列合并 left=DataFrame({'key':['foo1','foo2'],'lval':[1,2]}) print(left) right=DataFrame({'key':['foo1','foo2'],'rval':[4,5]}) m=pd.merge(left,right,on='key') print(m) ''' key lval rval 0 foo1 1 4 1 foo2 2 5 ''' right=DataFrame({'key':['foo2','foo1'],'rval':[4,5]}) m=pd.merge(left,right,on='key') print(m) ''' key lval rval 0 foo1 1 5 1 foo2 2 4 自动按key排序 ''' #数据插入 s1=tips.iloc[4] print(tips.append(s1))#在最后插入s1 ''' .. ... ... ... ... ... ... ... 242 17.82 1.75 Male No Sat Dinner 2 243 18.78 3.00 Female No Thur Dinner 2 4 24.59 3.61 Female No Sun Dinner 4 ''' #如果想忽略原来的顺序 print(tips.append(s1,ignore_index=True)) ''' .. ... ... ... ... ... ... ... 242 17.82 1.75 Male No Sat Dinner 2 243 18.78 3.00 Female No Thur Dinner 2 244 24.59 3.61 Female No Sun Dinner 4 ''' #排序 print(tips.sort_values('tip'))#如果tip相同是随机排序 print(tips.sort_values(['tip','total_bill']))#如果tip相同按照total_bill排序 print(tips.sort_values('tip',ascending=False))#降序排列 print(tips.sort_values(['sex','tip'],ascending=[True,False]))#sex是升序,tip是降序 #groupby 按组来分 print(tips.groupby('sex').sum()) ''' total_bill tip size sex Female 1570.95 246.51 214 Male 3256.82 485.07 413 ''' print(tips.groupby(['sex','size']).sum()) ''' total_bill tip sex size Female 1 20.39 3.83 2 889.69 146.65 3 301.66 45.50 4 272.51 36.19 5 29.85 5.14 6 56.85 9.20 Male 1 8.58 1.92 2 1676.20 256.19 3 582.89 83.44 4 786.19 116.82 5 120.49 15.00 6 82.47 11.70 ''' print(tips.groupby(['sex','size']).var())#计算方差 print(tips.groupby(['sex','size']).mean())#计算均值 print(tips.groupby(['sex','time']).mean()) print(tips.groupby(['time','sex']).mean()) #以上运用的是自带函数,也可以自己写函数:运用apply #print(tips.apply(lambda x:x.max()-x.min())) 报错,因为字符串做减法没有意义 print(tips[['total_bill','tip','size']].apply(lambda x:x.max()-x.min())) ''' 类别型变量 有限的取值:如性别,年级,星座 加减乘除没有意义 分为有序(改进程度)和无序(性别) ''' s=pd.Series(['a','b','c','a'],dtype='category') print(s)#定义三个类别[a,b,c] s=pd.Series(['a','b','c','a']) s_cat=s.astype('category',categories=['b','c','d'],ordered=False) print(s_cat) ''' 0 NaN 1 b 2 c 3 NaN dtype: category Categories (3, object): [b, c, d] ''' s_cat=s.astype('category',categories=['b','c','d'],ordered=True) print(s_cat) ''' 0 NaN 1 b 2 c 3 NaN dtype: category Categories (3, object): [b < c < d] ''' tips['sex']=tips['sex'].astype('category') print(tips.dtypes) ''' total_bill float64 tip float64 sex category (改为类别型变量,如果在排序) smoker object day object time object size int64 dtype: object ''' print(tips['sex'].describe()) tips['sex']=tips['sex'].cat.set_categories(['Male','Female'],ordered=True)#按照Male,Female顺序排序 print(tips.sort_values(['sex','tip'],ascending=[True,False])) #Scipy from scipy import stats tips['pct']=tips['tip']/tips['total_bill'] tips['pct'].hist(bins=50) plt.show() np.random.seed(12798)#括号里的数任意取,表示随机取值,每次都是这些数 x=stats.t.rvs(10,size=1000)#自由度为10的,服从t分布的,1000个随机数 print(x.max(),x.min(),x.mean(),x.var()) n,(smin,smax),sm,sv,ss,sk=stats.describe(x) print(n,(smin,smax),sm,sv,ss,sk) #数据量,(最大最小值),均值,方差,偏度,峰度 #sv是样本方差,无偏的,除以n-1 #x.var()是有偏的,除以n m,v,s,k=stats.t.stats(10,moments='mvsk') print(m,v,s,k) #求出自由度为10的t分布框架,与上面对比,但是这种方法不严谨 print(stats.ttest_1samp(x,m))#1samp只有一个样本 #Ttest_1sampResult(statistic=-0.4793265213314117, pvalue=0.6318112653498806) #假设x服从t分布,均值为m #p值越大,不能拒绝原假设 print(stats.kstest(x,'t',(10,))) #KstestResult(D statistic=0.02278131347716633, pvalue=0.6770476966689749) print(stats.kstest(x,'norm',(x.mean(),x.std()))) #KstestResult(D statistic=0.038041733200022354, pvalue=0.10786689196970567) #P值变小,但是也不能拒绝样本服从正态分布 quantiles=[0,0.01,0.05,0.1,0.9,0.95,0.99,1] #定义区间 crit=stats.t.ppf(quantiles,10) print(crit)#生成自由度为10的,分位数 n_sample=x.size print(np.histogram(x,bins=crit))#把x按照quantiles的分割方法放入 ''' (array([ 10, 51, 45, 795, 45, 48, 6], dtype=int64), array([ -inf, -2.76376946, -1.81246112, -1.37218364, 1.37218364, 1.81246112, 2.76376946, inf])) ''' freqcount=np.histogram(x,bins=crit)[0] print(freqcount) #[ 10 51 45 795 45 48 6] tprob=np.diff(quantiles) print(tprob) #[0.01 0.04 0.05 0.8 0.05 0.04 0.01] #t分布,落在quantiles中每个区间内的概率 nprob=np.diff(stats.norm.cdf(crit)) tch,tpval=stats.chisquare(freqcount,tprob*n_sample) #卡方检验 print(tch,tpval) #7.256249999999978 0.2977981904272286 #P值较大,不能拒绝原假设,可能服从t分布 nch,npval=stats.chisquare(freqcount,nprob*n_sample) print(nch,npval) #42.81282529958775 1.270258060911676e-07 #P值很小,所以拒绝原假设,不服从正态分布 #t分布尾部要比正态分布厚,更适合金融变量 #基于样本估计数字特征进行卡方检验 tdof,tloc,tscale=stats.t.fit(x) #自由度,期望,方差;fit做数据拟合 nloc,nscale=stats.norm.fit(x) tprob=np.diff(stats.t.cdf(crit,tdof,loc=tloc,scale=tscale)) nprob=np.diff(stats.norm.cdf(crit,loc=nloc,scale=nscale)) tch,tpval=stats.chisquare(freqcount,tprob*n_sample) print(tch,tpval) #7.221777984801926 0.3008235281454931 nch,npval=stats.chisquare(freqcount,nprob*n_sample) print(nch,npval) #7.734582610834106 0.2582004821347473 #都不能拒绝,因为尾部的区别被中部的相同性所掩盖 ''' 假设检验: 假设数据服从一个分布,数据落在某一区间内的概率是一定的 如果出现小概率事件,就应该拒绝原假设 一般把不轻易否定的假设设为原假设 第一类错误:H0为真,但拒绝H0,即有小概率事件发生 可以通过显著性水平大小控制第一类错误发生概率 显著性水平越小,发生第一类错误可能性越小 第二类错误:H0为假,但接受H0 也不能使显著性水平太小,否则会导致第二类错误可能性增大 只能增加样本容量,才能同时降低第一类错误和第二类错误发生概率 功效分析: 1.功效:1-P(二型错误发生概率) 2.显著性水平:P(一型错误发生概率) 3.样本大小:n 4.效应值:ES 可以分辨的范围 ''' #正态分布检验 print(stats.normaltest(x)) #NormaltestResult(statistic=28.7002708835221, pvalue=5.85889025395807e-07) #P值很小,拒绝原假设 print(stats.normaltest(tips['tip'])) #NormaltestResult(statistic=79.37862574074785, pvalue=5.796294322907102e-18) #P值很小,拒绝原假设 tips.pct.hist(bins=50) plt.show() print(stats.normaltest(tips['pct'])) #NormaltestResult(statistic=220.8879728815828, pvalue=1.0833932598440914e-48) #看起来很像正态分布,但P值很小,不是正态分布,猜测是由右边的值引起的 print(tips[tips['pct']>0.4]) ''' total_bill tip sex smoker day time size pct 172 7.25 5.15 Male Yes Sun Dinner 2 0.710345 178 9.60 4.00 Female Yes Sun Dinner 2 0.416667 ''' #去除异常点 tips1= tips.drop([172,178]) print(stats.normaltest(tips1['pct'])) #NormaltestResult(statistic=4.684342675054582, pvalue=0.09611870532870112) tips1['pct'].hist(bins=50) plt.show() #图中看出还有一个大于0.3的可能是异常点 print(tips[tips['pct']>0.3]) tips1= tips.drop([67,172,178]) print(stats.normaltest(tips1['pct'])) #NormaltestResult(statistic=0.7724869721322898, pvalue=0.6796050311777623) #P值约等于0.68,不能拒绝原假设 tips1['pct'].hist(bins=50) plt.show() #比较两个样本 #比较均值 rvs1=stats.norm.rvs(loc=5,scale=10,size=500) rvs2=stats.norm.rvs(loc=5,scale=10,size=500) print(stats.ttest_ind(rvs1,rvs2)) #Ttest_indResult(statistic=1.5805691598040679, pvalue=0.11429344105879968) rvs3=stats.norm.rvs(loc=8,scale=10,size=500) print(stats.ttest_ind(rvs1,rvs3)) #Ttest_indResult(statistic=-5.099916335277352, pvalue=4.065109029217463e-07) #P值很小,拒绝原假设,第一组和第二组均值不同 #比较两组分布 print(stats.ks_2samp(rvs1,rvs2)) #Ks_2sampResult(statistic=0.07000000000000006, pvalue=0.16580778180902778) print(stats.ks_2samp(rvs1,rvs3)) #Ks_2sampResult(statistic=0.14400000000000002, pvalue=5.3169784499192515e-05) #P值很小,可以拒绝原假设