数据分析行业薪资的秘密,你想知道的都在这里(2)

接上篇:数据分析行业薪资的秘密,你想知道的都在这里(1)

第二部分:职位信息清洗及数据提取

数据分析师的收入怎么样?哪些因素对于数据分析的薪资影响最大?哪些行业对数据分析人才的需求量最高?我想跳槽,应该选择大公司大平台还是初创的小公司?按我目前的教育程度,工作经验,和掌握的工具和技能,能获得什么样水平的薪资呢?

我们使用python抓取了2017年6月26日拉钩网站内搜索“数据分析”关键词下的450条职位信息。通过对这些职位信息的分析和建模来给你答案。

本系列文章共分为五个部分,分别是数据分析职位信息抓取,数据清洗及预处理,数据分析职位分布分析,数据分析薪资影响因素分析,以及数据建模和薪资预测。这是第二篇:职位信息清洗及数据提取。

第二篇文章是对获取的数据进行清洗,预处理和特征提取。在第一篇文章中我们抓取了拉勾网的450条职位信息及职位描述。但这些信息无法直接用于数据分析,我们需要对抓取到的信息进行清洗,规范现有数据的格式,提取信息中的数据及特征,为后续的数据分析和建模做准备。下面开始介绍苦逼的

数据清洗流程介绍。

数据清洗前的准备工作

首先是开始前的准备工作,导入所需要的库文件,包括常用的numpy和pandas库用于计算平均薪资以及对字符进行分列等操作,正则表达式re库用于字符的查找和替换操作,结巴分词库jieba用于对职位描述进行分词操作,自然语言处理nltk库用于计算职位描述的文字丰富度指标,还有KMeans用于对平均

薪资进行聚类操作。


  1. #导入所需库文件 
  2. import re 
  3. import numpy as np 
  4. import pandas as pd 
  5. import jieba as jb 
  6. import jieba.analyse 
  7. import jieba.posseg as pseg 
  8. import nltk 
  9. from sklearn import preprocessing 
  10. from sklearn.cluster import KMeans  

导入我们之前抓取并保存的数据表,并查看数据表的维度以及各字段名称。后面我们会经常使用这些字段名称。


  1. #导入之前抓取并保存的数据表 
  2. lagou=pd.DataFrame(pd.read_csv('lagou_data_analysis_2017-06-26.csv',header=0,encoding='GBK')) 
  3.   
  4. #查看数据表维度及字段名称 
  5. lagou.columns,lagou.shape  

职位信息清洗及预处理

开始对职位信息的各个字段进行清洗和预处理,主要清洗的内容包括文本信息提取和处理,内容搜索和替换,字段内的空格处理,数值信息提取和计算,英文字母统一大小写等等。我们将先展示清洗前的原始字段,然后在展示清洗后的新字段内容。

行业字段清洗及处理

第一个清洗的字段是行业字段,抓取到的行业字段比较混乱,有些只有一个行业名称,有些则有两级的行业名称。我们保留行业字段第一部分的信息,对有两部分行业名称的字段取前一个。


  1. #查看原始industryField字段信息 
  2.  
  3. lagou[['industryField']].head()  

由于行业名称之间有的以顿号分割,有的以逗号分割,我们先将所有的分隔符统一为逗号,然后对这个字段进行分列。并将分列后的字段重新拼接回原数据表中。


  1. #对industryField字段进行清洗及分列 
  2. #创建list存储清洗后的行业字段 
  3. industry=[] 
  4. #将顿号分隔符替换为逗号 
  5. for x in lagou['industryField']: 
  6.     c=x.replace("、", ",") 
  7.     industry.append(c) 
  8. #替换后的行业数据改为Dataframe格式     
  9. industry=pd.DataFrame(industry,columns=["industry"]) 
  10. #对行业数据进行分列 
  11. industry_s=pd.DataFrame((x.split(',') for x in industry["industry"]),index=industry["industry"].index,columns=['industry_1','industry_2']) 
  12. #将分列后的行业信息匹配回原数据表 
  13. lagou=pd.merge(lagou,industry_s,right_index=True, left_index=True) 
  14. #清除字段两侧空格 
  15. lagou["industry_1"]=lagou["industry_1"].map(str.strip)  

以下是清洗后的行业字段。


  1. #查看清洗后的行业字段 
  2.  
  3. lagou[["industry_1","industry_2"]].head() 

融资阶段字段清洗及处理

第二个清洗的字段是融资阶段字段,抓取下来的原始信息中对融资阶段进行了双重标识,例如成长型(A轮)。由于第一个标识”成长型”定义比较宽泛,我们提取第二个括号中的标识。


  1. #查看清洗前的financeStage字段 
  2.  
  3. lagou[['financeStage']].head()  

首先建立一个字典,将数据表中融资阶段的每一条信息与字典中的Key进行查找。如果融资阶段信息中包含字典中的任何一个key,我们就把这个key对应的value记录下来。


  1. #提取并处理financeStage中的融资信息 
  2. #创建一个字典 
  3. f_dict = {'未融资':'未融资', 
  4.           '天使轮':'天使轮', 
  5.           'A轮':'A轮', 
  6.           'B轮':'B轮', 
  7.           'C轮':'C轮', 
  8.           'D轮':'D轮', 
  9.           '不需要':'不需要融资', 
  10.           '上市公司':'上市公司' 
  11.           } 
  12. #创建list存储清洗后的信息 
  13. financeStage2=[] 
  14. #逐一提取financeStage字段中的每一条信息 
  15. for i in range(len(lagou['financeStage'])): 
  16.     #逐一提取字典中的每一条信息 
  17.     for (key, value) in f_dict.items(): 
  18.         #判断financeStage字段中是否包含字典中的任意一个key 
  19.         if key in lagou['financeStage'][i]: 
  20.             #如何包含某个key,则把对应的value保存在list中 
  21.             financeStage2.append(value) 
  22. #把新保存的list添加到原数据表中             
  23. lagou["financeStage1"]=financeStage2  

  1. #查看清洗后的financeStage字段 
  2.  
  3. lagou[["financeStage1"]].head() 

职位名称字段清洗及处理

第三个清洗的字段是职位名称,这里我们要提取职位里的title信息。没有title信息的都统一归为其他。具体方法是将每个职位名称与现有的title列表逐一判断,如果职位名称中含有title关键字就被划分到这个类别下。否则被归为其他类。


  1. #查看清洗前的positionName字段 
  2.  
  3. lagou[['positionName']].head()  

 


  1. #提取并处理positionName中的职位信息 
  2. #创建list存储清洗后的信息 
  3. positionName3=[] 
  4. #对职位名称进行判断归类 
  5. for i in range(len(lagou['positionName'])): 
  6.     if '实习' in lagou['positionName'][i]: 
  7.         positionName3.append("实习") 
  8.     elif '助理' in lagou['positionName'][i]: 
  9.         positionName3.append("助理") 
  10.     elif '专员' in lagou['positionName'][i]: 
  11.         positionName3.append("专员") 
  12.     elif '主管' in lagou['positionName'][i]: 
  13.         positionName3.append("主管") 
  14.     elif '经理' in lagou['positionName'][i]: 
  15.         positionName3.append("经理") 
  16.     elif '专家' in lagou['positionName'][i]: 
  17.         positionName3.append("专家") 
  18.     elif '总监' in lagou['positionName'][i]: 
  19.         positionName3.append("总监") 
  20.     elif '工程师' in lagou['positionName'][i]: 
  21.         positionName3.append("工程师") 
  22.     else: 
  23.         #以上关键词都不包含的职位归为其他 
  24.         positionName3.append("其他") 
  25. #把新保存的list添加到原数据表中         
  26. lagou["positionName1"]=positionName3  

  1. #查看清洗后的positionName字段 
  2.  
  3. lagou[["positionName1"]].head()  

薪资范围字段清洗及处理

第四个清洗的字段是薪资范围。抓取到的数据中薪资范围是一个区间值,比较分散,无法直接使用。我们对薪资范围进行清洗,去掉无关的信息并只保留薪资上限和下限两个数字,然后使用这两个数字计算出平均薪资值。


  1. #查看清洗前的salary字段 
  2.  
  3. lagou[['salary']].head()  


  1. #提取并计算平均薪资 
  2. #创建list用于存储信息 
  3. salary1=[] 
  4. #对salary字段进行清洗 
  5. for i in lagou['salary']: 
  6.     #设置要替换的正则表达式k|K 
  7.     p = re.compile("k|K") 
  8.     #按正则表达式对salary字段逐条进行替换(替换为空) 
  9.     salary_date = p.sub("", i) 
  10.     #完成替换的信息添加到前面创建的新list中 
  11.     salary1.append(salary_date) 
  12. #将清洗后的字段合并到原数据表中 
  13. lagou['salary1']=salary1 
  14. #对薪资范围字段进行分列 
  15. salary_s=pd.DataFrame((x.split('-') for x in lagou['salary1']),index=lagou['salary1'].index,columns=['s_salary1','e_salary1']) 
  16. #更改字段格式 
  17. salary_s['s_salary1']=salary_s['s_salary1'].astype(int) 
  18. #更改字段格式 
  19. salary_s['e_salary1']=salary_s['e_salary1'].astype(int)  

  1. #计算平均薪资 
  2.  
  3. #创建list用于存储平均薪资 
  4.  
  5. salary_avg=[] 
  6.  
  7. #逐一提取薪资范围字段 
  8.  
  9. for i in range(len(salary_s)): 
  10.  
  11. #对每一条信息字段计算平均薪资,并添加到平均薪资list中。 
  12.  
  13. salary_avg.append((salary_s['s_salary1'][i] + salary_s['e_salary1'][i])/2) 
  14.  
  15. #将平均薪资拼接到薪资表中 
  16.  
  17. salary_s['salary_avg']=salary_avg 
  18.  
  19. #将薪资表与原数据表进行拼接 
  20.  
  21. lagou=pd.merge(lagou,salary_s,right_index=True, left_index=True)  

  1. #查看清洗以后的salary_avg字段 
  2.  
  3. lagou[["salary_avg"]].head()  

职位信息中的数据提取

在职位描述字段中,包含了非常详细和丰富的信息。比如数据分析人才的能力要求和对各种数据分析工具的掌握程度等。我们对这个字段的一些特征进行指标化,对有价值的信息进行提取和统计。

职位描述字段中的数据提取

第五个清洗的字段是职位描述,准确的说从职位描述字段中提取信息。职位描述中包含了大量关于职位信息,工作内容,和个人能力方面的信息,非常有价值。但无法直接拿来使用。需要进行信息提取。我们将对职位描述字段进行三方面的信息提取。

第一是提取职位描述中对于个人能力的要求,换句话说就是数据分析人员使用工具的能力。我们整理了10个最常见的数据分析工具。来看下每个职位描述中都出行了哪些工具名称。由于一些工具间存在可替代性,所以每个职位描述中可能会出现多个工具的名称。没出现一个工具名称,我们就会在相应的工具下表示1,如果没有出现则标识为0。


  1. #查看清洗以前的job_detail字段 
  2.  
  3. lagou[['job_detail']].head()  


  1. #提取职位描述字段,并对英文统一转化为小写 
  2. lagou['job_detail']=lagou['job_detail'].map(str.lower) 
  3. #提取职位描述中的工具名称 
  4. tools=['sql','python','excel','spss','matlab','sas','r','hadoop','spark','tableau'] 
  5. #创建list用于存储数据 
  6. tool=np.array([[0 for i in range(len(tools))] for j in range(len((lagou['job_detail'])))]) 
  7. #逐一提取职位描述信息 
  8. for i in range(len(lagou['job_detail'])): 
  9.     #逐一提取工具名称 
  10.     for t in tools: 
  11.         #获得工具名称的索引位置(第几个工具) 
  12.         index=tools.index(t) 
  13.         #判断工具名称是否出现在职位描述中 
  14.         if t in lagou['job_detail'][i]: 
  15.             #如果出现,在该工具索引位置(列)填1 
  16.             tool[i][index]=1 
  17.         else: 
  18.             #否则在该工具索引位置(列)填0 
  19.             tool[i][index]=0 
  20. #将获得的数据转换为Dataframe格式             
  21. analytics_tools=pd.DataFrame(tool,columns=tools) 
  22. #按行(axis=1)对每个职位描述中出现的工具数量进行求和 
  23. tool_num=analytics_tools.sum(axis=1) 
  24. #将工具数量求和拼接到原数据表中 
  25. analytics_tools["tool_num"]=tool_num 
  26. #将表与原数据表进行拼接 
  27. lagou=pd.merge(lagou,analytics_tools,right_index=True, left_index=True)  

  1. #查看从job_detail中提取的分析工具信息 
  2.  
  3. lagou[['sql','python','excel','spss','matlab','sas','r','hadoop','spark','tableau','tool_num']].head()  

职位描述所使用的字数统计

第二是计算职位描述所使用的字数,我们猜测初级简单的工作描述会比较简单,而高级复杂的工作描述则会更复杂一些。因此职位描述中不同的字数里也可能隐藏着某种信息或关联。


  1. #计算职位描述的字数 
  2. #创建list用于存储新数据 
  3. jd_num=[] 
  4. #逐一提取职位描述信息 
  5. for i in range(len(lagou['job_detail'])): 
  6.     #转换数据格式(list转换为str) 
  7.     word_str = ''.join(lagou['job_detail'][i]) 
  8.     #对文本进行分词 
  9.     word_split = jb.cut(word_str) 
  10.     #使用|分割结果并转换格式 
  11.     word_split1 = "| ".join(word_split) 
  12.     #设置字符匹配正则表达式 
  13.     pattern=re.compile('\w') 
  14.     #查找分词后文本中的所有字符并赋值给word_w 
  15.     word_w=pattern.findall(word_split1) 
  16.     #计算word_w中字符数量并添加到list中 
  17.     jd_num.append(len(word_w)) 
  18. #对字符数量进行归一化     
  19. min_max_scaler = preprocessing.MinMaxScaler() 
  20. min_max_jd_num = min_max_scaler.fit_transform(jd_num) 
  21. #将归一化的数据添加到原数据表中 
  22. lagou['jd_num']=min_max_jd_num  

  1. #查看职位描述字数 
  2.  
  3. jd_num[:10]  


  1. #查看归一化的职位描述字段 
  2.  
  3. lagou[['jd_num']].head()  

职位描述的词汇丰富度统计

第三是计算职位描述中的文字丰富度指标。和前面的字数统计一样。初级职位所对应的工作会相对简单,在描述上也会比较简单。高级职位则可能需要更详细的和负责的描述。因此文字丰富度指标上也会更高一些。


  1. #计算职位描述文字丰富度 
  2. #创建新list用于存储数据 
  3. diversity=[] 
  4. #逐一提取职位描述信息 
  5. for i in range(len(lagou['job_detail'])): 
  6.     #转换数据格式(list转换为str) 
  7.     word_str = ''.join(lagou['job_detail'][i]) 
  8.     #将文本中的英文统一转化为小写 
  9.     word_str=word_str.lower() 
  10.     #查找职位描述中的所有中文字符 
  11.     word_list=re.findall(r'[\u4e00-\u9fa5]', word_str) 
  12.     #转换数据格式(list转换为str) 
  13.     word_str1=''.join(word_list) 
  14.     #对文本进行分词 
  15.     word_split = jb.cut(word_str1) 
  16.     #使用空格分割结果并转换格式 
  17.     word_split1 = " ".join(word_split) 
  18.     #使用nltk对句子进行分词 
  19.     tokens = nltk.word_tokenize(word_split1) 
  20.     #转化为text对象 
  21.     text = nltk.Text(tokens) 
  22.     #计算职位描述的文字丰富度(唯一词/所有词) 
  23.     word_diversity=len(set(text)) / len(text) 
  24.     #将文本词汇丰富度数据添加到list中 
  25.     diversity.append(word_diversity) 
  26. #将文字丰富度匹配到原数据表中    
  27. lagou["diversity"]=diversity  

  1. #查看职位描述丰富度字段 
  2.  
  3. lagou[["diversity"]].head() 

对数据分析的薪资进行聚类

完成清洗和数据提取后,平均薪资已经比薪资范围要具体的多了,但仍然比较离散。我们对这些平均薪资进行聚类来支持后面的建模和预测工作。以下是具体的代码和聚类结果。我们将类别标签添加到原始数据表中。


  1. #提取平均工作年限,平均薪资和平均公司规模字段 
  2. salary_type = np.array(lagou[['salary_avg']]) 
  3. #进行聚类分析 
  4. clf=KMeans(n_clusters=3) 
  5. #训练模型 
  6. clf=clf.fit(salary_type) 
  7. #将距离结果标签合并到原数据表中 
  8. lagou['cluster_label']= clf.labels_ 
  9. #输出聚类结果 
  10. clf.cluster_centers_  

聚类后平均薪资被分为三个类别,第1类是薪资均值为19.3K的区间,分类标记为0。第二类是薪资均值为8.2K的区间,分类标记为1,。第三类是薪资均值为32.1的区间,分类标记为3。


  1. #对平均薪资进行聚类预测 
  2. clf.predict(9),clf.predict(25),clf.predict(30)  


  1. #查看数据表中的类别标识字段 
  2.  
  3. lagou[['salary_avg','cluster_label']].head()  

查看清洗及处理后的数据表

到这里我们完成了对450个职位信息的字段清洗和数据提取工作。下面我们再来查看下数据表的维度,名称以及数据表中的数据。在下一篇文章中我们将使用这个数据表对数据分析职位的分布情况以及薪资的影响因素进行分析,并通过建模对薪资收入进行预测。


  1. #查看数据表维度及字段名称 
  2.  
  3. lagou.columns,lagou.shape 


  1. #查看清洗完的数据表 
  2.  
  3. lagou.head() 

本文作者:王彦平

来源:51CTO

时间: 2024-09-20 21:27:12

数据分析行业薪资的秘密,你想知道的都在这里(2)的相关文章

数据分析行业薪资的秘密,你想知道的都在这里(1)

第一部分,数据分析职位信息抓取 数据分析师的收入怎么样?哪些因素对于数据分析的薪资影响最大?哪些行业对数据分析人才的需求量最高?我想跳槽,应该选择大公司大平台还是初创的小公司?按我目前的教育程度,工作经验,和掌握的工具和技能,能获得什么样水平的薪资呢? 我们使用python抓取了2017年6月26日拉钩网站内搜索"数据分析"关键词下的450条职位信息.通过对这些职位信息的分析和建模来给你答案. 本系列文章共分为五个部分,分别是数据分析职位信息抓取,数据清洗及预处理,数据分析职位需求分析

mfc求助-50个picture控件 我想把他们都初始化为一个颜色

问题描述 50个picture控件 我想把他们都初始化为一个颜色 50个picture控件 我想把他们都初始化为一个颜色,怎么弄....... 解决方案 这 不是很清楚,唉... 解决方案二: 在picture父组件上,循环查找picture,设置颜色

Lotus做的OA,历史数据比较多,domino慢的厉害,想把数据都归档下来,有没有好的办法?

问题描述 Lotus做的OA,历史数据比较多,domino慢的厉害,想把数据都归档下来,有没有好的办法? 解决方案 解决方案二:有公司提出类似的解决方案,应该可以解决你的问题公司名称好像是索易信解决方案三:我们是按年份做归档解决方案四:刚网上查了一下,公司网址是www.soyxer.com解决方案五:首先你要确认,归档数据归档后,十分还需要经常性的查询?如果不需要经常性的查询,那么,建议直接做库拆分.这样直接使用的库内容就少了.如果还要经常性的查询,那么做个归档方案吧.比如一个文到了结束环节之后

九个大家都想做但都没有做成功的创新产品

中介交易 SEO诊断 淘宝客 云主机 技术大厅 创业公司的成功靠什么?一个超赞的点子?这远远不够.仅靠概念不能成就一家企业. 但是,一个尚未成功的理念并不意味着它始终不会成功.这在科技领域表现的尤为明显,你会看到成功者出现前会有无数"前浪"被拍死在沙滩上.以下就是国外科技媒体The Next Web总计的9个大家都想做但都没有做成功的产品类型. 1. 照片组群分享 照片组群分享类的初创企业很常见,一些值得注意的产品包括Adobe's GroupPix, Color,Yogile,Goo

数据分析行业需要具备哪些技术 如何快速进入

大数据如此火爆的时代,各种人才倍受青睐.视野决定了境界和能力,而所处的环境又决定了视野.好多人不知道什么是数据分析师,认为会熟练使用Excel就是数据分析师,如果你还会使用Excel中的一些高级功能如透视和函数等等,可能别人就认为你是牛*的数据分析师了,如果你工作中还用到了VBA,(word天啊!),在别人眼中你就是数据分析大神了.真的是这样吗?诚然,单用Excel的确可以解决大部分的数据问题,但是作为一个数据分析师,你并不是一个基层的统计分析从业者,那么数据分析师应该是怎样的职业呢? (一)数

不入虎穴焉得虎子:揭秘培训行业那些不为人知的秘密!

其实很多的SEOer或是网络推广人员都是半路出家,或为了生活的所迫,或是很看好这一行业前景.但是他们存在的最大问题是不懂技术,不知道应该怎么做?既然不懂就要学啊,这样就滋生了现在网上很火的一个行业--培训.今天还有一个朋友问我:我想学SEO和网络营销,但是不知道参加哪一个培训?这个问题空城也很难回答,因为现在的培训市场太乱,充斥着太多的虚假宣传.为了让各位朋友避免上当受骗,空城在这冒"大不韪"检举下培训行业的黑幕,不针对任何机构,只是就事论事!因为空城也参加过很多培训,"深入

刘登攀被抓,揭露微信刷粉行业背后的秘密

上周,电商业内人士龚文祥微博爆料称,国内最大的微信吸粉公司新菜鸟公司创始人刘登攀被抓,但具体原因不明.近日经警方及新菜鸟员工证实,刘登攀确实于去年12月29日左右被警方带走. 多方消息证实刘登攀被抓 传闻称,"刘登攀收了传统企业共7000万元,目前已被腾讯报深圳南山公安分局被抓",其担任创始人的新菜鸟是全国排名第一的机器加粉服务商,公司增加粉丝有一个比较专业的流程,包括: 1.数据采集:2.数据切割:3.微信开通过滤:4.规则测试:5.微信多开:6.信息推送:7.微信初始化:8.自动加

IT行业薪资吸引眼球,网游从业者月薪超8000元职位数量占比最高

前程无忧昨日发布最新数据,长期热门的IT行业再次以薪资高吸引眼球,其中网络游戏领域从业者月薪超8000元职位数量占比最高. 2014年三季度全国IT类职能的网上发布职位数逾56万个,较2014年一季度增长22%,受"金九银十"小高峰的影响,增长幅度也明显高于二季度. 同步发布的"2014年四季度求职者跳槽意愿度调查"则显示,IT行业中技术类岗位的加薪幅度领先其他岗位,其中计算机软件行业的加薪幅度较大,涨幅超过5%的企业不在少数,而受央企高管限薪方案的影响,电信服务等

以色列网络安全行业崛起的秘密

中国网络安全行业向以色列学习什么 --看以色列是如何让网络安全初创企业遍地开花的 目前以色列国内拥有超过300家网络安全企业,这也使其掌握着仅次于美国的全球第二大安全产业规模. 2014年年内,以色列网络安全企业的出口总值达到60亿美元,相当于全球网络安全市场整体规模的10%左右. 在2015年,这一比例预计迎来进一步增长:全球安全市场整体规模较上一年增长约25%,而以色列网络安全初创企业数量则新增81家. 这些网络安全初创企业在投资生态系统当中保持着优势地位,占据到以色列国内同期全部投资的16