第三章 数据探索
3.1 数据质量分析
3.1.1 缺失值分析
3.1.2 异常值分析
import pandas as pd
catering_sale = '../data/catering_sale.xls' #餐饮数据
data = pd.read_excel(catering_sale, index_col = u'日期')
#读取数据,指定“日期”列为索引列
print(data.describe())
销量
count 200.000000
mean 2755.214700
std 751.029772
min 22.000000
25% 2451.975000
50% 2655.850000
75% 3026.125000
max 9106.440000
#-*- coding: utf-8 -*-
import pandas as pd
catering_sale = '../data/catering_sale.xls' #餐饮数据
data = pd.read_excel(catering_sale, index_col = u'日期') #读取数据,指定“日期”列为索引列
print(data.describe())
import matplotlib.pyplot as plt #导入图像库
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号
plt.figure() #建立图像
p = data.boxplot(return_type='dict') #画箱线图,直接使用DataFrame的方法
x = p['fliers'][0].get_xdata() # 'flies'即为异常值的标签
y = p['fliers'][0].get_ydata()
y.sort() #从小到大排序,该方法直接改变原对象
#用annotate添加注释
#其中有些相近的点,注解会出现重叠,难以看清,需要一些技巧来控制。
#以下参数都是经过调试的,需要具体问题具体调试。
for i in range(len(x)):
if i>0:
plt.annotate(y[i], xy = (x[i],y[i]), xytext=(x[i]+0.05 -0.8/(y[i]-y[i-1]),y[i]))
else:
plt.annotate(y[i], xy = (x[i],y[i]), xytext=(x[i]+0.08,y[i]))
plt.show() #展示箱线图
3.1.3 一致性分析
3.2 数据特征分析
3.2.1 分布分析
- 定量数据的分布分析
- 定性数据的分布分析
3.2.2 对比分析
3.2.3 统计量分析
# 餐饮销量数据统计量分析
import pandas as pd
catering_sale = './data/catering_sale.xls'
data = pd.read_excel(catering_sale,index_col = u'日期')
# 过滤异常数据
data = data[(data[u'销量'] > 400)&(data[u'销量'] < 5000)]
statistics = data.describe()
# 极差
statistics.loc['range'] = statistics.loc['max'] - statistics.loc['min']
# 变异系数
statistics.loc['var'] = statistics.loc['std'] / statistics.loc['mean']
# 四分位数间距
statistics.loc['dis'] = statistics.loc['75%'] - statistics.loc['25%']
销量
count 195.000000
mean 2744.595385
std 424.739407
min 865.000000
25% 2460.600000
50% 2655.900000
75% 3023.200000
max 4065.200000
range 3200.200000
var 0.154755
dis 562.600000
3.2.4 周期性分析
3.2.5 贡献度分析
- 有误-已改
# 菜品盈利帕累托图代码
import pandas as pd
# 初始化参数
dish_profit = './data/catering_dish_profit.xls'
data = pd.read_excel(dish_profit,index_col = u'菜品名')
data = data[u'盈利'].copy()
# 表示按降序排列
data.sort_values(ascending=False)
# 导入图像库
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False
plt.figure()
# 显示直方图
data.plot(kind='bar')
plt.ylabel(u'盈利(元)')
p = 1.0 * data.cumsum()/data.sum()
p.plot(color = 'r',secondary_y=True,style='-o',linewidth=2)
# 添加注释,即85%处的标记,这里包括了指定箭头样式
plt.annotate(format(p[6],'.4%'),xy=(6,p[6]),xytext=(6*0.9,p[6]*0.9),
arrowprops=dict(arrowstyle="->",connectionstyle="arc3,rad=.2"))
plt.ylabel(u'盈利')
plt.show()
3.2.6 相关性分析
#-*- coding: utf-8 -*-
#餐饮销量数据相关性分析
from __future__ import print_function
import pandas as pd
catering_sale = '../data/catering_sale_all.xls' #餐饮数据,含有其他属性
data = pd.read_excel(catering_sale, index_col = u'日期') #读取数据,指定“日期”列为索引列
print(data)
a=data.corr() #相关系数矩阵,即给出了任意两款菜式之间的相关系数
b=data.corr()[u'百合酱蒸凤爪'] #只显示“百合酱蒸凤爪”与其他菜式的相关系数
c=data[u'百合酱蒸凤爪'].corr(data[u'翡翠蒸香茜饺']) #计算“百合酱蒸凤爪”与“翡翠蒸香茜饺”的相关系数
print(a,b,c)
百合酱蒸凤爪 翡翠蒸香茜饺 金银蒜汁蒸排骨 乐膳真味鸡 ... 铁板酸菜豆腐 香煎韭菜饺 香煎罗卜糕 原汁原味菜心
日期 ...
2015-01-01 17 6 8 24 ... 18 10 10 27
2015-01-02 11 15 14 13 ... 19 13 14 13
2015-01-03 10 8 12 13 ... 7 11 10 9
2015-01-04 9 6 6 3 ... 9 13 14 13
2015-01-05 4 10 13 8 ... 17 11 13 14
2015-01-06 13 10 13 16 ... 12 11 5 9
2015-01-07 9 7 13 8 ... 10 8 10 7
2015-01-08 9 12 13 6 ... 6 12 11 5
2015-01-12 6 8 8 3 ... 5 5 7 10
2015-01-13 9 11 13 6 ... 6 9 8 9
2015-01-14 6 7 8 9 ... 8 5 3 10
2015-01-15 5 9 4 7 ... 15 9 13 9
2015-01-16 9 7 11 9 ... 14 9 9 15
2015-01-17 10 8 10 6 ... 16 9 4 14
2015-01-18 13 12 12 10 ... 8 12 9 15
2015-01-19 4 8 12 11 ... 10 6 11 11
2015-01-20 6 12 10 9 ... 8 14 6 13
2015-01-21 9 15 4 12 ... 1 5 12 8
2015-01-22 3 10 13 13 ... 13 5 11 11
2015-01-23 8 7 9 20 ... 8 7 8 11
2015-01-24 11 6 11 8 ... 9 7 10 9
2015-01-25 11 6 5 15 ... 14 7 6 8
2015-01-26 4 7 10 7 ... 9 12 7 5
2015-01-27 7 5 6 7 ... 6 12 9 4
2015-01-28 8 8 12 14 ... 7 12 10 6
2015-01-29 4 10 12 9 ... 8 10 10 11
2015-01-30 6 7 7 11 ... 9 16 10 11
2015-01-31 8 5 11 10 ... 8 10 10 9
2015-02-01 8 6 7 9 ... 6 11 6 9
[29 rows x 10 columns]
百合酱蒸凤爪 翡翠蒸香茜饺 金银蒜汁蒸排骨 ... 香煎韭菜饺 香煎罗卜糕 原汁原味菜心
百合酱蒸凤爪 1.000000 0.009206 0.016799 ... 0.127448 -0.090276 0.428316
翡翠蒸香茜饺 0.009206 1.000000 0.304434 ... 0.062344 0.270276 0.020462
金银蒜汁蒸排骨 0.016799 0.304434 1.000000 ... 0.121543 0.077808 0.029074
乐膳真味鸡 0.455638 -0.012279 0.035135 ... -0.068866 -0.030222 0.421878
蜜汁焗餐包 0.098085 0.058745 0.096218 ... 0.155428 0.171005 0.527844
生炒菜心 0.308496 -0.180446 -0.184290 ... 0.038233 0.049898 0.122988
铁板酸菜豆腐 0.204898 -0.026908 0.187272 ... 0.095543 0.157958 0.567332
香煎韭菜饺 0.127448 0.062344 0.121543 ... 1.000000 0.178336 0.049689
香煎罗卜糕 -0.090276 0.270276 0.077808 ... 0.178336 1.000000 0.088980
原汁原味菜心 0.428316 0.020462 0.029074 ... 0.049689 0.088980 1.000000
[10 rows x 10 columns] 百合酱蒸凤爪 1.000000
翡翠蒸香茜饺 0.009206
金银蒜汁蒸排骨 0.016799
乐膳真味鸡 0.455638
蜜汁焗餐包 0.098085
生炒菜心 0.308496
铁板酸菜豆腐 0.204898
香煎韭菜饺 0.127448
香煎罗卜糕 -0.090276
原汁原味菜心 0.428316
Name: 百合酱蒸凤爪, dtype: float64 0.009205803051836475
进程已结束,退出代码0
3.3 Python主要数据探索函数
3.3.1 基本统计特征函数
- corr
- 例子:计算两个列向量的相关系数:
import pandas as pd
# 计算两个列的相关系数
# 生成样本D,一行为1-7,一行为2-8
D = pd.DataFrame([range(1,8),range(2,9)])
# 提取第一行
S1 = D.loc[0]
# 提取第二行
S2 = D.loc[1]
# 计算S1,S2的相关系数:有person(皮尔逊系数),kendall(肯德尔系数),spearman(斯皮尔曼系数)
print(S1.corr(S2,method='pearson'))
1.0
- cow
- 计算协方差矩阵:
# 计算协方差矩阵
import numpy as np
import pandas as pd
D = pd.DataFrame(np.random.randn(6,5)) # 产生6*5的随机矩阵
a=D.cov() #计算协方差矩阵
b=D[0].cov(D[1]) # 计算第一列和第二列的协方差
print(a)
print(b)
0 1 2 3 4
0 0.521355 -0.294786 -0.604556 -0.117828 -0.292401
1 -0.294786 0.547336 0.100784 0.288286 0.041412
2 -0.604556 0.100784 1.896650 -0.399878 0.691623
3 -0.117828 0.288286 -0.399878 0.629655 -0.181989
4 -0.292401 0.041412 0.691623 -0.181989 0.642261
-0.29478647521293616
- skew/kurt
- 计算 6 * 5 随机矩阵的偏度(三阶矩)/峰度(四阶矩)
# 计算 6 * 5 随机矩阵的偏度(三阶矩)/峰度(四阶矩)
import pandas as pd
import numpy as np
D = pd.DataFrame(np.random.randn(6,5)) # 产生6*5的随机矩阵
# 偏度:通过对偏度系数的测量,我们能够判定数据分布的不对称程度以及方向
a=D.skew()
# 峰度:是研究数据分布陡峭或平滑的统计量,通过对峰度系数的测量,我们能够判定数据分布相对于正态分布而言是更陡峭还是平缓。
b=D.kurt()
print(a,'\n',b)
0 0.480378
1 0.809317
2 -0.471835
3 0.285682
4 0.351842
dtype: float64
0 -1.191099
1 -1.008232
2 -0.838486
3 -2.291016
4 0.333473
dtype: float64
- describle
- 计算 6 * 5 随机矩阵的describle
import pandas as pd
import numpy as np
D = pd.DataFrame(np.random.randn(6,5)) # 产生6*5的随机矩阵
print(D.describe())
0 1 2 3 4
count 6.000000 6.000000 6.000000 6.000000 6.000000
mean -0.222618 0.000732 0.287847 0.490553 -0.355000
std 1.503612 0.812898 1.175178 1.021233 1.010684
min -1.864585 -1.092559 -0.655483 -1.302156 -2.092816
25% -1.341961 -0.416813 -0.545182 0.340578 -0.478626
50% -0.516123 -0.125909 -0.218693 0.531917 -0.206985
75% 0.846039 0.462691 0.871330 1.044542 -0.118080
max 1.878268 1.203656 2.239292 1.689423 1.034402
3.3.2 拓展统计特征函数
- cum和pd.rolling_系列函数
- 有误-已改
import pandas as pd
import numpy as np
D = pd.Series(range(0,5))
print(D)
print(D.cumsum())
print(D.rolling(2).sum()) #修改了
0 0
1 1
2 2
3 3
4 4
dtype: int64
0 0
1 1
2 3
3 6
4 10
dtype: int64
0 NaN
1 1.0
2 3.0
3 5.0
4 7.0
dtype: float64
3.3.3 统计作图函数
- plot
import matplotlib.pyplot as plt # 导入作图库
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.figure(figsize = (7,5)) # 创建图像区域,指定比例
import numpy as np
#设置起点,终点和步长
x = np.linspace(0, 2*np.pi, 50) # x坐标输入
y = np.sin(x) # 计算对应x的正弦值
plt.plot(x, y, 'bp--') # 控制图形格式为蓝色带星虚线,显示正弦曲线
plt.show()
- pie
import matplotlib.pyplot as plt
labels = 'Frogs','Hogs','Dogs','Logs' # 定义标签
sizes = [15, 30, 45, 10] #每一块的比例
colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral'] #每一块的颜色
explode = (0,0.09,0,0) # 突出显示,这里仅仅突出第二块
plt.pie(sizes,explode=explode, labels=labels, colors=colors, autopct='%1.1f%%',
shadow=True, startangle=90)
plt.axis('equal') #显示为圆(避免比例压缩为椭圆)
plt.show()
- hist
import matplotlib.pyplot as plt
import numpy as np
x = np.random.randn(1000) # 1000个服从正态分布的随机数
plt.hist(x, 10) # 分成10组进行绘制直方图
plt.show()
- boxplot
'''
绘制箱型图的两种方法:
- 直接调用DataFrame的boxplot()方法;
- 调用Series或者DataFrame的plot()方法,并用kind参数指定箱型图(box);
'''
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
x = np.random.randn(1000) # 1000个服从正态分布的随机数
D = pd.DataFrame([x,x+1]).T # 构造两列的DataFrame
D.plot(kind = 'box') # 调用Series内置的作图方法画图,用kind参数指定箱型图box
plt.show()
- plot(logx = True)
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
import numpy as np
import pandas as pd
# np.arrange()返回一个ndarray而不是一个列表
x = pd.Series(np.exp(np.arange(20))) # 原始数据
# 对图像左上方做好标记
x.plot(label = u'原始数据图',legend = True)
plt.show()
x.plot(logy = True, label = u'对数数据图',legend = True)
plt.show()
- plot(yerr = error)
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
import numpy as np
import pandas as pd
error = np.random.randn(10) # 定义误差列
y = pd.Series(np.sin(np.arange(10))) #均值数据列
y.plot(yerr = error) #绘制误差图
plt.show()