【Python数据分析基础笔记(仅供本人学习记录)】P6.数据分析方法

7.7 数据分析方法

pandas的数据分析方法包括基本统计分析,分组统计分析,分布分析,交叉分析,结构分析和相关分析等

7.7.1基本统计分析

基本统计分析又称为描述性统计分析,一般统计某个变量的个数、均值、标准差、最小值、25%分位值、50%分位值、75%分位值、以及最大值。
描述性统计分析的功能是按各列返回基本统计量和分位数,函数的语法格式:  DataFrame.describe() 或 DataFrame.columns.describe()

【例】3
在grade.xls文件中包含有学号(std_id),平时成绩(normal)和期末考试成绩(exam)这3列数据,要求对改文件中的期末考试成绩(exam)列的数据进行统计分析,并进行计数,求最大值和均值的计算

import numpy as np
import pandas as pd
from pandas import DataFrame,Series
df=pd.read_excel('p:\data\grade.xls',sheet_name='grade')
print('学生成绩表为:\n',df)
学生成绩表为:
      stu_id  Normal   exam
0   2017001       80    66
1   2017002       87    67
2   2017003       85    60
3   2017004       80    55
4   2017005       76    44
5   2017006       90    76
6   2017007       84    68
7   2017008       90    83
8   2017009       88    80
9   2017010       90    74
10  2017011       75    57
11  2017012       70    45
12  2017013       81    62
13  2017014       86    83
14  2017015       87    74
15  2017016       89    82
16  2017017       84    60
17  2017018       80    60
18  2017019       91    85
19  2017020       86    61
20  2017021       91    81
21  2017022       70    32
22  2017023       95    81
23  2017024       88    91
24  2017025       88    84
25  2017026       91    80
26  2017027       91    89
27  2017028       90    83
28  2017029       88    68
29  2017030       74    47
30  2017031       81    50
31  2017032       78    48
32  2017033       81    60
33  2017034       84    89
34  2017035       87    79
35  2017036       82    70
36  2017037       89    60
37  2017038       90    64
print('exam列描述性统计分析:\n',df.exam.describe())
exam列描述性统计分析:
 count    38.000000
mean     68.368421
std      14.695874
min      32.000000
25%      60.000000
50%      68.000000
75%      81.000000
max      91.000000
Name: exam, dtype: float64
print('exam列个数:\n',df.exam.size)
exam列个数:
 38
print('exam列的最大值',df.exam.max())
exam列的最大值 91
print('exam列的均值',df.exam.mean())
exam列的均值 68.36842105263158

7.7.2 分组分析

分组分析是指根据分组字段,将分析对象划分成不同的部分,以进行对比分析各组之间的差异性的一种分析方法。分组分析常用的统计指标是计数、求和、平均值。
分组统计函数的语法格式:(书中的写法已经弃用:见官方文档:https://pandas.pydata.org/pandas-docs/stable/whatsnew/v0.25.0.html)
DataFrame.groupby([‘id’])[‘click’].agg([(click_std=‘std’)]).reset_index()

函数的参数说明:

  • id:用于分组的列
  • 中括号[]:用于统计的列
  • agg:统计别名用于显示统计值的名称,统计函数用于统计数据,常用的统计函数有计数(size),求和(sum),均值(mean)

【例】在Employee_income.xls文件中包含有职工号(emp_id)、性别(sex)、年龄(age)、学历(education)、参加工作的时间(firstjob)、工作地区(region)、行业(industry)、职业(occupation)、月薪(salary)、月补贴(subsidy)等十项数据,要求分别按年龄、学历分组统计人数,并求月薪的均值,最大值和最小值。其示例代码如下:

import numpy as np
from pandas import DataFrame
import pandas as pd
df=pd.read_excel('P:\data\Employee_income.xls',sheet_name='emp_income')
df
emp_idsexageeducationfirstjobregionindustryoccupationsalarysubsidy
03030本科2011-07-20广州机械技术员5000500
115423高中2014-06-23广州机械操作工25001500
24028大专2011-07-20广州机械文员3800200
34130本科2011-07-20广州机械技术员4500500
44245研究生2000-09-22广州机械主管76991000
54337高中2000-03-23广州商业店员3500600
64436大专2003-03-24广州商业主管45001000
716525高中2012-07-21长沙机械文员2500500
815636本科2007-09-22长沙机械技术员4500500
915438研究生2004-08-12长沙机械主管65001000
103023高中2013-06-23长沙机械操作工20001000
1115428大专2011-07-20长沙机械文员3000300
124037高中2000-03-23长沙商业店员2500500
1316536大专2003-03-24长沙商业主管35001000
1415637高中2013-06-23长沙商业店员28001000
1515436本科2011-07-20长沙商业主管45001000
164628高中2007-03-23广州商业店员30001500
174736本科2003-03-24广州商业主管50001500
age_result = df.groupby('age')['salary'].agg([
    ('人数',np.size),
    ('平均月薪',np.mean),
    ('最高月薪',np.max),
    ('最低月薪',np.min),
])
age_result
人数平均月薪最高月薪最低月薪
age
2322250.00000025002000
2512500.00000025002500
2833266.66666738003000
3024750.00000050004500
3654400.00000050003500
3732933.33333335002500
3816500.00000065006500
4517699.00000076997699
edu_result=df.groupby('education')['salary'].agg([('人数',np.size),('平均月薪',np.mean),
                                                 ('最高月薪',np.max),('最低月薪',np.min)])
edu_result
人数平均月薪最高月薪最低月薪
education
大专43700.00000045003000
本科54700.00000050004500
研究生27099.50000076996500
高中72685.71428635002000

7.7.3分布分析

分布分析是指根据分析的目的,将定量数据进行等距或者不等距的分组,进行研究各组分布规律的一种分析方法。如学生成绩分布、用户年龄分布、收入状况分布等。
分布分析cut函数的语法格式:
pandas.cut(x,bins,right=True,labels=None,retbins=False,precision=3,
       Include_lowest=False) 

函数参数说明:

  • x:进行划分的一维数组
    -**bins:取整数值,表示将x划分为多少个等距的区间。**取序列值,表示将x划分在指定序列中,若不在该序列中,则是NaN
    -right:分组时是否包含右端点,默认为True(包含)
  • labels:分组时是否用自定义标签来代替返回的bins,可选项,默认为NULL
  • precision:表示精度,默认为3
  • include_lowest:分组时是否包含左端点,默认为False(不包含)

注意:在分布分析时,先用cut()函数确定分布分析中的分层,然后再用groupby()函数实现分组分析。

import numpy as np
import pandas as pd
df=pd.read_excel('p:/data/Employee_income.xls',sheet_name='emp_income')
print('分层前的数据:\n')
df
分层前的数据:
emp_idsexageeducationfirstjobregionindustryoccupationsalarysubsidy
03030本科2011-07-20广州机械技术员5000500
115423高中2014-06-23广州机械操作工25001500
24028大专2011-07-20广州机械文员3800200
34130本科2011-07-20广州机械技术员4500500
44245研究生2000-09-22广州机械主管76991000
54337高中2000-03-23广州商业店员3500600
64436大专2003-03-24广州商业主管45001000
716525高中2012-07-21长沙机械文员2500500
815636本科2007-09-22长沙机械技术员4500500
915438研究生2004-08-12长沙机械主管65001000
103023高中2013-06-23长沙机械操作工20001000
1115428大专2011-07-20长沙机械文员3000300
124037高中2000-03-23长沙商业店员2500500
1316536大专2003-03-24长沙商业主管35001000
1415637高中2013-06-23长沙商业店员28001000
1515436本科2011-07-20长沙商业主管45001000
164628高中2007-03-23广州商业店员30001500
174736本科2003-03-24广州商业主管50001500
#年龄分布状况
age_bins=[20,30,40,50,60]
age_labels=['20-30岁','31-40岁','41-50岁','51-60岁']
df['年龄分层']=pd.cut(df.age,age_bins,labels=age_labels)
print('分层后的数据:\n')
df
分层后的数据:
emp_idsexageeducationfirstjobregionindustryoccupationsalarysubsidy年龄分层
03030本科2011-07-20广州机械技术员500050020-30岁
115423高中2014-06-23广州机械操作工2500150020-30岁
24028大专2011-07-20广州机械文员380020020-30岁
34130本科2011-07-20广州机械技术员450050020-30岁
44245研究生2000-09-22广州机械主管7699100041-50岁
54337高中2000-03-23广州商业店员350060031-40岁
64436大专2003-03-24广州商业主管4500100031-40岁
716525高中2012-07-21长沙机械文员250050020-30岁
815636本科2007-09-22长沙机械技术员450050031-40岁
915438研究生2004-08-12长沙机械主管6500100031-40岁
103023高中2013-06-23长沙机械操作工2000100020-30岁
1115428大专2011-07-20长沙机械文员300030020-30岁
124037高中2000-03-23长沙商业店员250050031-40岁
1316536大专2003-03-24长沙商业主管3500100031-40岁
1415637高中2013-06-23长沙商业店员2800100031-40岁
1515436本科2011-07-20长沙商业主管4500100031-40岁
164628高中2007-03-23广州商业店员3000150020-30岁
174736本科2003-03-24广州商业主管5000150031-40岁
#分组统计人数、平均月薪、最高月薪、最低月薪
aggResult=df.groupby('年龄分层')['salary'].agg([('人数',np.size),('平均月薪',np.mean),
                                           ('最高月薪',np.max),('最低月薪',np.min)])
aggResult
人数平均月薪最高月薪最低月薪
年龄分层
20-30岁8.03287.5000005000.02000.0
31-40岁9.04144.4444446500.02500.0
41-50岁1.07699.0000007699.07699.0
51-60岁NaNNaNNaNNaN

7.7.4 交叉分析

交叉分析通常是用于分析两个或两个以上分组变量之间的关系,以交叉表形式进行变量间关系的对比分析;从数据的不同维度,综合进行分组细分,进一步了解数据的构成、分布特征。

1.透视表

交叉分析有数据透视表和交叉表两种,其中,pivot_table()函数返回值是数据透视表的结果,该函数相当于excel中的数据透视表功能。

pivot_table()函数格式如下:
pandas.pivot_table(data,values,index,columns,aggfunc,fill_value,margins)

dataframe.pivot_table(values,index,columns,aggfunc,fill_value,margins)
参数说明如下:

  • data:要应用透视表的数据框
  • values:待聚合的列的名称,默认为聚合所有数值列
  • index:用于分组的列名或其他分组键,出现在结果透视表的行
  • columns:用于分组的列名或其他分组键,出现在结果透视表的列
  • aggfunc:用于聚合函数或函数列表,默认为’mean’,可以是任何对groupby有效的函数
  • fill_value:用于替换结果表中的缺失值
  • margins:添加行/列小计和总计

注意:在交叉分析时,先用cut()函数确定交叉分析中的分层,然后再用pivot_table()函数实现交叉分析。

【例】对Employee_income.xls文件中的数据进行下列交叉分析
(1)、对年龄(age)和性别(sex)数据列进行交叉分析,求解不同年龄段中不同性别的人数
(2)、对年龄(age)和学历(education)数据列进行交叉分析,求解不同年龄段不同学历员工的平均月薪。
代码如下:

import numpy as np
import pandas as pd
df=pd.read_excel('p:/data/Employee_income.xls',sheet_name='emp_income')
#年龄分布状况
age_bins=[20,30,40,50,60,70]
age_labels=['20-29岁','30-39岁','40-49岁','50-59岁','60-69岁']
df['年龄分层']=pd.cut(df.age,age_bins,labels=age_labels)
print('分层后的数据:\n')
df
分层后的数据:
emp_idsexageeducationfirstjobregionindustryoccupationsalarysubsidy年龄分层
03030本科2011-07-20广州机械技术员500050020-29岁
115423高中2014-06-23广州机械操作工2500150020-29岁
24028大专2011-07-20广州机械文员380020020-29岁
34130本科2011-07-20广州机械技术员450050020-29岁
44245研究生2000-09-22广州机械主管7699100040-49岁
54337高中2000-03-23广州商业店员350060030-39岁
64436大专2003-03-24广州商业主管4500100030-39岁
716525高中2012-07-21长沙机械文员250050020-29岁
815636本科2007-09-22长沙机械技术员450050030-39岁
915438研究生2004-08-12长沙机械主管6500100030-39岁
103023高中2013-06-23长沙机械操作工2000100020-29岁
1115428大专2011-07-20长沙机械文员300030020-29岁
124037高中2000-03-23长沙商业店员250050030-39岁
1316536大专2003-03-24长沙商业主管3500100030-39岁
1415637高中2013-06-23长沙商业店员2800100030-39岁
1515436本科2011-07-20长沙商业主管4500100030-39岁
164628高中2007-03-23广州商业店员3000150020-29岁
174736本科2003-03-24广州商业主管5000150030-39岁
#求不同年龄段中不同性别的人数年龄分布状况
ptResult1=df.pivot_table(
    values=['age'],
    index=['年龄分层'],
    columns=['sex'],
    aggfunc=[np.size]
    
)
ptResult1
size
age
sex
年龄分层
20-29岁4.04.0
30-39岁4.05.0
40-49岁NaN1.0
#求不同年龄段不同学历的平均月薪
ptResult2=df.pivot_table(
      values=['salary'],
index=['年龄分层'],
columns=['education'],
aggfunc=[np.mean])
ptResult2
mean
salary
education大专本科研究生高中
年龄分层
20-29岁3400.04750.000000NaN2500.000000
30-39岁4000.04666.6666676500.02933.333333
40-49岁NaNNaN7699.0NaN

2、交叉表

交叉表(cross-tabulation, 简称crosstab)是一种用于计算分组频率的特殊透视表。

交叉表crosstab()函数语法格式如下:

pandas.crosstab(index,columns,values=None,rownames=None,colnames=None,
aggfunc=None,margines=False,margine=False,margine_name=‘ALL’,
dropna=True,normalize=False)

参数说明如下:

  • index:接收array、Series或数组列表,表示要在行中分组的值
  • columns:接收array、Series或数组列表,表示在列中分组的值
  • values:接收array,可选。根据因素聚合的值数组。需要指定“aggfunc”
  • rownames:接收sequence,默认为none。如果传递,则必须匹配传递的行数组。
  • colnames:接收sequence,默认为none。如果传递,则必须匹配传递的列数组。
  • aggfunc:聚合函数或函数列表
  • margines:添加行/列小计和总计,默认为False
  • margine_name:接收string,默认为“ALL”,表示包含总计的行/列的名称

【例】利用交叉表分析Employee_income.s=xls文件中的不同性别的学历人数,其代码如下

import numpy as np
import pandas as pd
df=pd.read_excel('P:\data\Employee_income.xls',sheet_name='emp_income')
print('表中的数据为:\n',df)

#按性别分组,统计各组中学历的频数
ctResult=pd.crosstab(df['sex'],df['education'],margins=True)
print('按性别分组,统计各组中学历的频数情况如下:\n',ctResult)
表中的数据为:
     emp_id sex  age education   firstjob region industry occupation  salary  \
0       30   男   30        本科 2011-07-20     广州       机械        技术员    5000   
1      154   男   23        高中 2014-06-23     广州       机械        操作工    2500   
2       40   女   28        大专 2011-07-20     广州       机械         文员    3800   
3       41   女   30        本科 2011-07-20     广州       机械        技术员    4500   
4       42   男   45       研究生 2000-09-22     广州       机械         主管    7699   
5       43   男   37        高中 2000-03-23     广州       商业         店员    3500   
6       44   女   36        大专 2003-03-24     广州       商业         主管    4500   
7      165   女   25        高中 2012-07-21     长沙       机械         文员    2500   
8      156   男   36        本科 2007-09-22     长沙       机械        技术员    4500   
9      154   男   38       研究生 2004-08-12     长沙       机械         主管    6500   
10      30   男   23        高中 2013-06-23     长沙       机械        操作工    2000   
11     154   男   28        大专 2011-07-20     长沙       机械         文员    3000   
12      40   女   37        高中 2000-03-23     长沙       商业         店员    2500   
13     165   女   36        大专 2003-03-24     长沙       商业         主管    3500   
14     156   男   37        高中 2013-06-23     长沙       商业         店员    2800   
15     154   男   36        本科 2011-07-20     长沙       商业         主管    4500   
16      46   女   28        高中 2007-03-23     广州       商业         店员    3000   
17      47   女   36        本科 2003-03-24     广州       商业         主管    5000   

    subsidy  
0       500  
1      1500  
2       200  
3       500  
4      1000  
5       600  
6      1000  
7       500  
8       500  
9      1000  
10     1000  
11      300  
12      500  
13     1000  
14     1000  
15     1000  
16     1500  
17     1500  
按性别分组,统计各组中学历的频数情况如下:
 education  大专  本科  研究生  高中  All
sex                            
女           3   2    0   3    8
男           1   3    2   4   10
All         4   5    2   7   18

总而言之,在交叉分析中,透视表pivot_table()是一种进行分组统计的函数,参数aggfunc决定统计类型;而交叉表crosstab()是一种特殊的pivot_table(),专门用于计算分组的频率。

7.7.5结构分析

结构分析是在分组以及交叉的基础上,计算各组成部分所占的比重,进而分析总体的内部特征的一种分析方法。
在结构分析时,先利用pivot_table()函数进行数据透视表分析,然后,通过axis参数指定对数据透视表按行或列进行计算(当axis=0时按列计算,axis=1时按行计算)。

在这里插入图片描述

【例】对Employee_income.xls文件中的年龄(age)和学历(education)数据列进行结构分析,求不同年龄分层下各种学历的占比

import numpy as np
import pandas as pd
df=pd.read_excel('p:/data/Employee_income.xls',sheet_name='emp_income')
age_bins=[20,30,40,50,60,70]#年龄分布状况
age_labels=['20-29岁','30-39岁','40-49岁','50-59岁','60-69岁']
df['年龄分层']=pd.cut(df.age,age_bins,right=False,labels=age_labels)
ptResult=df.pivot_table(
values=['age'],
    index=['年龄分层'],
    columns=['education'],
    aggfunc=[np.size]
)
print(ptResult)
print(ptResult.sum())
print(ptResult.div(ptResult.sum(axis=0),axis=1))
#div的第一个参数是除法的分母,意思是按行把数据除以该列的总和
#即得到某一个年龄分层下的学历占比
          size               
           age               
education   大专   本科  研究生   高中
年龄分层                         
20-29岁     2.0  NaN  NaN  4.0
30-39岁     2.0  5.0  1.0  3.0
40-49岁     NaN  NaN  1.0  NaN
           education
size  age  大专           4.0
           本科           5.0
           研究生          2.0
           高中           7.0
dtype: float64
          size                    
           age                    
education   大专   本科  研究生        高中
年龄分层                              
20-29岁     0.5  NaN  NaN  0.571429
30-39岁     0.5  1.0  0.5  0.428571
40-49岁     NaN  NaN  0.5       NaN

7.7.6

相关分析(correlation analysis)是研究现象之间是否存在某种依存关系,并对具体有依存关系的现象探讨其相关方向以及相关程度,是研究随机变量之间相关关系的一种统计方法。

相关分析函数:DataFrame.corr()和Series.corr(other)
在这里插入图片描述

【例】分别计算Employee_income.xls文件中的年龄(age)与月薪(salary)的相关系数,年龄(age)与月薪(salary),补贴(subsidy)的相关系数,以及所有数据的相关系数矩阵

import pandas as pd
df=pd.read_excel('p:/data/Employee_income.xls',sheet_name='emp_income')
#计算age和salary相关系数
corrResult1=df.age.corr(df.salary)
print('age和salary相关系数',corrResult1)
age和salary相关系数 0.6781676305144909
#计算age和salary、subsidy的相关系数
corrResult2=df.loc[:,['age','salary','subsidy']].corr()
print('age和salary、subsidy的相关系数:\n',corrResult2)
age和salary、subsidy的相关系数:
               age    salary   subsidy
age      1.000000  0.678168  0.062137
salary   0.678168  1.000000  0.067629
subsidy  0.062137  0.067629  1.000000
#返回一个相关系数矩阵
print('返回一个相关系数矩阵\n',df.corr())
返回一个相关系数矩阵
            emp_id       age    salary   subsidy
emp_id   1.000000 -0.029849 -0.143666  0.043537
age     -0.029849  1.000000  0.678168  0.062137
salary  -0.143666  0.678168  1.000000  0.067629
subsidy  0.043537  0.062137  0.067629  1.000000

计算相关系数的corr()函数只会对数据框中的数据列进行计算

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TryBest_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值