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值很小,可以拒绝原假设