(数据和教程来自公众号:@秦路)
数据:DataAnalyst.csv (数据分析师招聘薪资)
使用工具:Jupyter Notebook
一、数据读取
导入数据,数据和代码需在同一文件夹下。参数encoding用来读取csv格式的编码,windows常见gb2312/utf-8。
二、数据概述
数据一共有6876行 ×17列,可以看出companyLabelList, businessZones, firstType, secondType, positionLables这几列有空值。comapnyId和positionId列为数字,其他列为字符串。
head函数显示头部数据,默认5,可自定义为其他数据;tail函数显示尾部数据。
三、数据清洗和整理
3.1查重并清洗掉重复行
positionId列为职位的唯一标识,unique函数返回唯一值,结合len函数求出共有5031个唯一值,小于总行数,说明有重复行。
去重函数drop_duplicates(subset,keep):参数subset值以哪一列为基准,keep参数选择保留first/last。去重后,数据集为5031行×17列。
3.2计算薪资的上下限
def cut_word定义函数,截取薪资,找出bottomSalary和topSalary。
find函数找出连接号‘-’的位置,bottomSalary为切片【开头至连接号前一位之间的数字】,topSalary为切片【连接号后一位至字段总长度前一位之间的数字】;如果salary字段为‘K以上’,没有连接号,则find函数返回值为-1,bottomSalary为切片【开头至K之间的数字】,此时设定topSalary等于bottomSalary。注意由于python大小写敏感,此处需用upper函数将字段转换成大写。
apply将函数应用到salary的所有行,并为数据集分别增加两列topSalary和bottomSalary。查看数据。
用astype函数将这两列数据格式转换成整数,若转换成功说明截取成功。
3.3求平均薪资
增加一列avgSalary,定义匿名函数lambda作为一次性函数,比def简便。word_cut函数apply针对series,此处是针对dataframe,axis=1表示应用于每行,axis=0表示应该于每列。
截取清洗后需要使用的部分列。
四、分析和可视化
4.1描述统计
分类数据描述统计函数:value_counts,统计非0元素个数,并按降序排列输出。可见北京的职位数量远高于其他城市。
数值数据描述统计函数:describe,得出平均薪资的mean,median,max,min,标准差,上分位数和下分位数。
4.2直方图
%matplotlib inline表示在jupyter的cell中输出图表。
用hist函数绘制平均薪资的直方图,横轴为薪资区间,纵轴为数量,参数bins为柱数,此处留空,则为默认值10。可见,平均薪资大部分集中在20k以下。
增加柱数可显示出更细的粒度,可见数据呈双峰状。
4.3箱线图
用boxplot函数绘制箱线图,查看不同城市平均薪资的变化。参数column选择纵坐标数值,by选择分类变量,figsize为尺寸。可见,北京的整体薪资高于其他城市,中位数尤其高,接下来是上海和深圳,然后是杭州。
备注:由于图表默认为英文字体,中文字体会无法显示,教程中采用的方法是每次作图时调用中文字体,这样需要多输入几行代码。此处已使用知乎@猴子的方法,一劳永逸解决了无法显示中文的问题,无需在每次画图时调用字体。
从学历来看,博士薪资整体领先,但上界低于本科和硕士,大专薪资整体最低。
从工作年限看来,工作十年以上的整体薪资遥遥领先,整体薪资水平随工作年限的增加而上升。
截取上海和北京的数据,横坐标取学历和城市双变量,可见不同学历背景下,北京的薪资都稍优于上海,博士学历下尤为明显。
4.4 Group by
单独使用groupby函数分组,并没有进行计算,故不返回结果。
使用groupby.cout函数,分组并将各列计数,此处得到的是dataframe,和之前的df_clean.city.value_counts函数的结果一致,但value_counts得到的是series且结果排序。
只显示上述dataframe其中的一列计数,则形式与df_clean.city.value_counts一致但不排序。
计算每个城市avgSalary列的mean,由于只有avgSalary列为数值,故只对该列进行计算。
按城市和学历分组计算平均薪资,得到层次化series。
用unstack函数将层次化series转置成dataframe,而stack函数可还原。可见,博士学历薪资最高在深圳,硕士学历薪资最高在杭州。
只统计平均工资列的计数结果,得到分层岗位数。
这种方法和上面对比结果一致,但是排序的,私以为视觉效果更好。
转置,可见要求博士学历的岗位数一共只有6个,故其平均薪资波动性很强。
用agg函数同时传入count和mean,按公司简称分组,对avgSalary同时求mean和计数。
将上述结果按count列的值以降序排列。
agg支持自定义函数,按不同公司分组,求每个公司avgSalary最大值和最小值的差值。
按不同城市,不同公司计数并排序,显示了全部。如何只显示前五大,如下:
定义topN函数,以city分组,对companyShortName调用topN函数,将不同城市按不同公司计数,按降序排列切片前五个。
只有一列数值时sort_values可省略by参数,apply可按组运算,支持更细粒度,而agg函数是对全部列。
求不同城市不同职位,显示职位数量前五大。
4.5 Group by作图
按城市分组,薪资均值柱状图。
多重指标分组柱状图,按不同城市不同学历分组的薪资均值柱状图,注意在作图前需转置。
4.6 对比直方图
将上海和北京的数据以直方图形式进行对比,x轴为城市的薪资,normed=1将纵轴转化为概率密度,面积之和为1,默认值0,由于两地人数差距大,故设定为密度;alpha表示透明度;facecolor设定颜色。
4.7堆积柱状图
用cut函数将薪资分桶并增加一列level,bins若只输入一个数字则等距划分,此处人工划分。返回的结果将每一行的avgSalary划分到了对应的level。
按不同城市不同level分组,按avgSalary计数并转置。
将每行数据转化为百分比形式,从而得到每个城市每个level薪资的占比情况。
堆积百分比柱状图,显示每个城市每个level薪资的占比情况。stacked=true表示将指标堆积。
附加:标签数据的处理
显示positionLables列。
去掉数据中的括号,str函数对列的每个字符串进行处理。df_clean.positionLables是Series,不能直接用replace函数。
用str.replace去除空格。
去掉空值,按照逗号拆分标签,apply函数将value_counts通常针对列的函数运用到行,使每个标签变成列标,统计每行数据各标签出现的次数,故大多是空值。
转置。
删除空值,重置为dataframe。level_0为标签名,level_1为职位的序号,0列为标签在该职位中出现的次数。
最后得到各个标签出现的次数。