数据分析师真的月入过万吗?(基于Python的招聘数据分析全流程实操)_python制作招聘数据

def drops(col, tag):
   cv.drop(cv[cv[col].str.contains(tag)].index, inplace=True) 

drops('职位名称', '实习') 

由于主流的工资标签格式都是前三类,因此删除其余格式的记录:

drops('薪资', '元/天'); drops('薪资', '/小时'); drops('薪资', '下/月'); drops('薪资', '上/月'); drops('薪资', '下/年'); drops('薪资', '上/年');

薪资列的类型是文本,不方便做统计分析,因此进行文本处理,分离出薪资下限、薪资上限、薪资标签,计算薪资均值,并统一以 千/月 为基准单位:

# 添加薪资标签,区分年薪和月薪,薪资单位千和万
# ['万/月':0, '万/年':1, '千/月':2]
cv['salary\_tag'] = np.where(cv['薪资'].str.contains('年'), 1, np.where(cv['薪资'].str.contains('千'),2 ,0))
cv['divisor'] =  np.where(cv['薪资'].str.contains('年'), 12, np.where(cv['薪资'].str.contains('千'),10 ,1))

cv['salary\_min'] = (cv['薪资'].apply(lambda x: str(x).split('-')[0]).astype('float') / cv['divisor'] \* 10).astype('int')
cv['salary\_max'] = (cv['薪资'].apply(lambda x: str(x).split('-')[1][:-3]).astype('float') / cv['divisor'] \* 10).astype('int')
cv['salary\_unit'] = cv['薪资'].apply(lambda x: str(x).split('-')[1][-3:])
cv['salary\_avg'] = (cv['salary\_min'] + cv['salary\_max']) / 2

通过观察升序后的薪资尾部数据,发现有部分异常大的离群值(个数均为1),因此删除部分离群值,便于后续分析统计与展示;

# 删掉部分离群值,薪资下限高于30k的,占比为0.59%
print(cv['salary\_min'].value_counts().tail(10))
#print((round((cv[cv['salary\_min'] > 30]['salary\_min'].count() / cv.shape[0] \* 100), 2)).astype('str') + '%' ) #Out: 0.59%
cv.drop(cv[cv['salary\_min'] > 30].index, inplace=True) 

img

至此,数据预处理暂告一段落。

数据分析和可视化

按照相关方法,对数据进行分析并通过可视化展示结果

  • 考虑到招聘单位往往按薪资区间的下限开工资,因此后续分析薪资时主要以薪资下限(对应列 cv[‘salary_min’] )做分析;
  • 通过按城市分类展示箱图发现,深圳的薪资表现整体都要优于广州;虽下四分位数持平,但其余指标深圳的表现均超过广州,说明数据分析相关的起步工作两地薪资持平,但发展空间和天花板实属深圳占优。
    img

箱图,按城市分类

  • 以薪资下限与上限为坐标,以城市为分类变量绘制散点图,观察薪资定位情况;可以发现,同样的薪资下限,深圳在薪资上限的表现会更加突出
    img
    薪资区间分布散点图
  • 从散点图也可以看出,薪资区间定位较为散乱,因此考虑对薪资利用cut()进行月薪重分类,分区方式参考“前程无忧”的过滤条件(此处区间为左闭右开,如 8-10 为 8k ≤ x<10k)
cv.salary_min.sort_values()
bins = [0, 2, 3, 4.5, 6, 8, 10, 15, 20, 30]
level = ['0-2','2-3','3-4.5','4.5-6','6-8','8-10','10-15','15-20','20-30']
cv['level'] = pd.cut(cv['salary\_min'], bins = bins, labels=level, right=False) #right=False表示左闭右开
cv_level = cv['level'].value_counts()

  • 对重采样后的薪资区间进行分类统计,可以发现,整体薪资分布符合721原则,即TOP 20%,中间70%,末尾10%;6-8k的月薪分布最多,占据了四分之一。
    img
  • 若将城市分类加入区间分布图,绘制叠加柱状图,结论大体如箱图所示
    img

薪资分布叠加柱状图

  • 做完了薪资整体分布的概览以及按城市分类对比后,发现“数据分析”岗位并没有想象中高薪,8k以下的月薪占比超过半数(55.43%),不过万的月薪占比更是接近四分之三(73.92%),那么究竟“月薪过万的数据分析师”是否唬人呢?
print('%.2f%%' %((cv[cv['salary\_min'] < 8].count() / cv.shape[0])['salary\_min'] \* 100))
print('%.2f%%' %((cv[cv['salary\_min'] < 10].count() / cv.shape[0])['salary\_min'] \* 100))
cv['salary\_min'].describe()

  • 挑选发布“数据分析”相关的职位名称用词频率前20名进行观察,发现大多数岗位都不符合“数据分析师”的头衔,但回到开头数据源的获取阶段,抓取的是含“数据分析”关键词的职位,而“数据分析”这个概念本身就非常宽泛,因为在实际工作中和数据打交道是司空见惯的事情,难易不同,主辅不同,工作性质不同,都会使得“数据分析”这项技能的实际应用有所不同。
cv.groupby(by=['职位名称'])['职位名称'].count().sort_values(ascending=False).head(20)

img

  • 因此考虑对职位名称的判断,添加分类变量列,来区分不同种类的工作:
    • 数据挖掘、算法工程师为一类,理解为偏技术数据分析类岗位(下简称挖掘岗);
      • 数据分析、BI、数据运营为一类,理解为偏业务数据分析类岗位(下简称分析岗);
      • 其余的判断为非数据分析类岗位(下简称其他岗)
# 对职位进行重分类:数据挖掘|算法 == 2, 数据分析|数据运营|BI == 1, 其余 == 0
is_skill = re.compile(r'数据挖掘|算法')
is_analyst = re.compile(r'数据分析|数据运营|BI')
cv['job\_type'] = np.where(cv['职位名称'].apply( lambda x: is_skill.search(x) != None ), 2, 
  np.where(cv['职位名称'].apply( lambda x: is_analyst.search(x) != None ), 1, 0))

  • 经过重新分类后,value_counts()的结果为:挖掘岗有174条、分析岗有1245条、其他岗为40443条;结合箱图分析,挖掘岗的整体表现远超过其余两类岗位,而分析岗相较于其他岗的起步更高,不过从高薪层面看则差距不大;
    img

箱图,按职位类别分类

  • 通过pandas的describe()也能反映不同职位类别的对比情况;回到刚提出的问题,数据分析工作是否稳妥月薪过万呢?从中位数的情况来看(此处不分析平均值,是因为预处理时删除了部分月薪过高的离群值,平均值可能偏低,但对中位数影响较小),并不乐观,分析岗的中位数仅为8k;
def salary\_type\_desc(col):
    type = cv.groupby('job\_type')[col].describe()
    all = pd.DataFrame(cv[col].describe()).T
    all.index = ['all']
    return pd.concat([type, all])

# 按职位分类的月薪统计信息(薪资下限)
salary_type_desc('salary\_min')

img

按职位分类的月薪统计信息(薪资下限)

  • 于是掏出了沉箱底已久的薪资均值、薪资上限,发现月入过万这个指标藏在了分析师的「薪资均值」中位数,以及“数据分析”相关岗位「薪资上限」中位数里。

img

按职位分类的月薪统计信息(薪资均值)

img

按职位分类的月薪统计信息(薪资上限)

  • 既然已经知道高薪往哪找,那么就来看看如何往心仪的岗位靠拢。首先尝试统计出常见技能的出现频次并绘制柱状图,可以发现排名前十的分别是:EXCEL、PPT、SQL、Python、MySQL、Hadoop、Oracle、SPSS、Spark、HIVE;
#关键词搜索函数封装,传入关键词列表,输出计数列表
def key\_list\_search(key):
    cnt = []
    for i in range(0, len(key)):
        cnt.append(cv[cv['职位信息'].str.contains(key[i])]['职位信息'].count())
    return cnt

img

  • 那么技能要求究竟和薪资是否挂钩呢?不妨来对技能与薪资的相关性进行评估,此处挑选了四大技能EXCEL、SQL、Python、Hadoop作为二分类变量,通过相关系数来评估相关性。
#定义匹配函数,挑选四个主流技能观察相关性
def is\_match(col, key):
    return cv[col].str.contains(key)
 
cv['is\_sql'] =np.where(is_match('职位信息', 'sql'), 1, 0)
cv['is\_python'] =np.where(is_match('职位信息', 'python'), 1, 0)
cv['is\_hadoop'] =np.where(is_match('职位信息', 'hadoop'), 1, 0)
cv['is\_excel'] =np.where(is_match('职位信息', 'excel'), 1, 0)

cv[['is\_excel', 'is\_sql', 'is\_python', 'is\_hadoop', 'salary\_min']].corr(method = 'spearman') 

  • 结果显示,四大技能均呈若弱相关,其中正相关性强弱排名为 Python ≥ SQL > Hadoop,而EXCEL呈现负相关;另外,值得注意的是 SQL 和 Python 通常在招聘要求上经常成对出现(其相关系数高达0.5)
    img
    四大技能相关系数矩阵

同样地,也将相关系数矩阵可视化(此处利用的是pandas_profiling)

img

关于Python学习资料:

在学习python中有任何困难不懂的可以微信扫描下方CSDN官方认证二维码加入python交流学习,互帮互助,这里有不错的学习教程和开发工具。
python兼职资源+python全套学习资料

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

二、Python必备开发工具

在这里插入图片描述

四、Python视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
在这里插入图片描述

文末有福利领取哦~

👉一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。img

👉二、Python必备开发工具

img
👉三、Python视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
img

👉 四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。(文末领读者福利)
img

👉五、Python练习题

检查学习结果。
img

👉六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
img

img

👉因篇幅有限,仅展示部分资料,这份完整版的Python全套学习资料已经上传

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里无偿获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值