项目说明
该项目的数据来源于2021年9月11日在拉勾网搜索“数据分析”,爬取的岗位信息。通过这些数据,主要回答以下几个问题:
1、各区对数据分析岗位的需求情况
2、各行业对数据分析岗位的需求情况
3、数据分析岗位的薪资状况
4、工作年限/学历与薪资的关系
5、不同规模的公司对工作经验的要求以及提供的薪资水平
各区需求情况
岗位需求绝大部分集中在南山区与福田区,这也于这些地区企业数量多有关
各行业的需求情况
排名前4的行业依次为:科技金融、数据服务、游戏、工具类产品,约占总需求的53%
排名前10的公司约占30%的岗位需求
由于头部公司需求大,且有跨行业的属性,如腾讯虽划位游戏行业,但还涉及其他行业,但不可否认这些行业确实比其他行业更需要数据分析
岗位薪资整体状况
绝大部分的工资分布在15k到30k间
从3个薪酬的中位数看,超过一半的工资在15K以上
从5%分位数看,大致只有5%的岗位开出工资低于10K
薪资的个数(count),平均值(mean),标准差(std),最小值(min),最大值(max),各百分位上的薪资大小
工作年限/学历与薪资的关系
绝大部分学历要本科
绝大部分有工作经历的要求
工作经历要求3-5年接近一半
不限的数据不明不做查看
本科学历需求多 学历越高起始工资越多
本科和硕士工作经历越长工资提升幅度在5年内差别不大
工作年限越长,薪资增长越多
公司规模与工作年限、薪资关系
对小公司(50人及以下)而言,大部分公司开出的薪资不会超过30k,规模更大的公司开的起更高的薪水
对工作年限小于3年的,公司规模与薪资关系不大;对工作年限超过3年,大公司开出的薪资更高
另一方面,从图中可以看到,当薪水超过30k时,公司对数据分析师的经验要求大多是3年以上,此时经验成为了较大的门槛。
其他
通过对职位标签的分析,可以看出
电商、金融、数据服务是数据分析岗位热门的领域
sql,python是数据分析岗位看重的工具
结论
各区需求情况
- 南山、福田几乎囊括的深圳数据分析岗位的绝大部分需求
各行业需求情况
- 电商、金融、数据服务是数据分析岗位需求的热门行业
薪资整体状况
- 绝大部分岗位工资集中在15k-30k
学历/工作经验情况
- 学历绝大部分要求是本科,约43%要求有3年以上的工作经验
- 学历越高起始工资越多,本科和硕士在5年内工资提升幅度差别不大
- 工作年限越长,薪资增长越多;
不同规模的公司对工作经验的要求以及提供的薪资水平
- 小公司很少有超过30k的岗位
- 对工作年限小于3年的岗位,公司规模与薪资关系不大;对工作年限超过3年,大公司开出的薪资更高
其他
- sql,python是数据分析岗位看重的工具
python代码
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
import wordcloud
from PIL import Image
#解决中文乱码问题
sns.set_style('white',{'font.sans-serif':['simhei','Arial']})
#导入数据
df = pd.read_excel('lagou.xlsx')
# df.shape #(402, 10)
#df.columns #(Index(['岗位名称', '公司名称', '发布时间', '薪资', '经验', '学历', '城市', '地区', '公司信息', '职位标签'], dtype='object')
df.head()
数据预处理
# 去掉岗位名称含有'实习'或'工作地点'的岗位
df=df[(~df['岗位名称'].str.contains('实习')) & (~df['岗位名称'].str.contains('工作地点'))]
#df.shape
#经验是[在校/应届生]或[1年以下]的改为[应届生]
df.replace(to_replace='在校/应届',value='应届生',inplace=True)
df.replace(to_replace='1年以下',value='应届生',inplace=True)
#运用正则表达式提取出薪资区间的中位数(作为薪资的平均值)、最小值、最大值
df['平均薪资'] = df['薪资'].str.extract(r'(\d+)[k]-(\d+)k')\
.applymap(lambda x:int(x))\
.mean(axis=1)
df['最小薪资'] = df['薪资'].str.extract(r'(\d+)[k]-(\d+)k')\
.applymap(lambda x:int(x))[0]
df['最大薪资'] = df['薪资'].str.extract(r'(\d+)[k]-(\d+)k')\
.applymap(lambda x:int(x))[1]
#对公司信息进行拆分
df['融资情况'] = df['公司信息'].str.split(' | ').str[0]
df.replace(to_replace='未融资',value='不需要融资',inplace=True)
df['公司规模'] = df['公司信息'].str.split(' | ').str[2]
# df['公司信息'].str.split(' | ').str[2].value_counts()
#处理行业信息
#只取公司信息行业的第一个行业(以符合,|、为分割取第一),并对某些描述相差不大的进行合并
def clean_industry(industry):
industry = industry.split(",")
industry =industry[0].split('|')[0].split("、")[0]
if '电商' in industry:
return '电商'
elif '人工智能服务' in industry:
return '人工智能'
elif '物流' in industry:
return '物流'
elif '服务' in industry and '企业服务' not in industry:
return '数据服务'
elif '金融' in industry:
return '科技金融'
else:
return industry
df['行业'] = df['公司信息'].str.split(' | ').str[4].map(clean_industry)
#df['行业'].unique().shape 共有32个行业
#最终游戏数据 387条
df.shape
#各区岗位需求情况
fig, ax = plt.subplots(figsize=(10,6))
sns.countplot(y='地区',order= df['地区'].value_counts().index,data=df,color='#3c7f99')
plt.box(False) #去掉图边框
fig.text(x=0, y=0.90, s=' 各区数据分析岗位的需求量 ',
fontsize=28, weight='bold', color='white', backgroundcolor='#c5b783')
plt.tick_params(axis='both', which='major', labelsize=16)
ax.xaxis.grid(which='both', linewidth=0.5, color='#3c7f99')
plt.xlabel('')
plt.ylabel('')
#各行业岗位需求情况
industry_index = df['行业'].value_counts()[:10].index
industry =df.loc[df['行业'].isin(industry_index),'行业']
ind_rate = df['行业'].value_counts(normalize = True)
ind_rate = ind_rate[:10].append(pd.Series({'其他':1-ind_rate[:10].sum()}))
fig, ax = plt.subplots(1,2,figsize=(15,6))
ax1=plt.subplot(121)
sns.countplot(y=industry.values,order = industry_index,color='#3c7f99',ax=ax1)
plt.box(False)
fig.text(x=0, y=0.90, s=' 细分领域数据分析岗位的需求量(取前十) ',
fontsize=32, weight='bold', color='white', backgroundcolor='#c5b783')
ax1.tick_params(axis='both', which='major', labelsize=10)
ax1.xaxis.grid(which='both', linewidth=0.5, color='#3c7f99')
plt.xlabel('')
plt.ylabel('')
ax2=plt.subplot(122)
sns.set_palette(sns.color_palette("PuBu_r"))
plt.pie(ind_rate, labels = ind_rate.index, autopct = '%.1f%%', startangle = 90,textprops={'fontsize': 10},counterclock = False)
plt.axis('square')
#防止被覆盖,最后加
ax1.xaxis.grid(which='both', linewidth=0.5, color='#3c7f99')
#前10的公司
com_index = df['公司名称'].value_counts()[:10].index
com =df.loc[df['公司名称'].isin(com_index),'公司名称']
com_rate = df['公司名称'].value_counts(normalize = True)
com_rate = com_rate[:10].append(pd.Series({'其他':1-com_rate[:10].sum()}))
fig, ax = plt.subplots(1,2,figsize=(15,6))
ax1=plt.subplot(121)
sns.countplot(y=com.values,order = com_index,color='#3c7f99',ax=ax1)
plt.box(False)
fig.text(x=0, y=0.90, s=' 公司数据分析岗位的需求量(取前十) ',
fontsize=32, weight='bold', color='white', backgroundcolor='#c5b783')
ax1.tick_params(axis='both', which='major', labelsize=10)
ax1.xaxis.grid(which='both', linewidth=0.5, color='#3c7f99')
plt.xlabel('')
plt.ylabel('')
ax2=plt.subplot(122)
sns.set_palette(sns.color_palette("PuBu"))
plt.pie(com_rate, labels = com_rate.index, autopct = '%.1f%%', startangle = 90,textprops={'fontsize': 10},counterclock = False)
plt.axis('square')
#防止被覆盖,最后加
ax1.xaxis.grid(which='both', linewidth=0.5, color='#3c7f99')
#前十名公司所属行业
top_com=pd.DataFrame(df['公司名称'].value_counts()[:10]).\
reset_index().rename(columns = {'index': '公司名称','公司名称': '岗位数'})
df1=df[['公司名称','行业']].drop_duplicates()
df1=pd.merge(top_com,df1,how='left',on='公司名称')[['公司名称','行业','岗位数']]
df1
#岗位的薪资状况
df[['最小薪资','平均薪资','最大薪资']].describe([0.01,0.05,0.1,0.25,0.5,0.75,0.9,0.99]).T
# 薪资分布状况
fig,ax = plt.subplots(figsize=(12,8))
fig.text(x=0.04, y=0.90, s=' 薪资分布对比 ',
fontsize=32, weight='bold', color='white', backgroundcolor='#c5b783')
sns.kdeplot(df['最大薪资'],shade=True,label='最大薪资',color='r')
sns.kdeplot(df['平均薪资'],shade=True,label='平均薪资',color='b')
sns.kdeplot(df['最小薪资'],shade=True,label='最小薪资',color='g')
plt.tick_params(axis='both', which='major', labelsize=16)
plt.box(False)
plt.xticks(np.arange(0,160,10), [str(i)+"k" for i in range(0,160,10)])
plt.yticks([])
plt.legend(fontsize = 'xx-large',fancybox=None) #是否将图例框的边角设为圆形
plt.grid(axis='x')
#岗位的学历/工作经验的要求高吗
job_edu = df['学历'].value_counts()
job_exp = df['经验'].value_counts()
fig, ax = plt.subplots(1,2,figsize=(12,8))
ax1=plt.subplot(121)
sns.set_palette(sns.color_palette("PuBu_r"))
plt.pie(job_edu, labels = job_edu.index, autopct = '%.1f%%', startangle = 90,textprops={'fontsize': 10},counterclock = False)
plt.axis('square')
fig.text(x=0, y=0.90, s=' 学历/工作经验的需求情况 ',
fontsize=32, weight='bold', color='white', backgroundcolor='#c5b783')
ax2=plt.subplot(122)
sns.set_palette(sns.color_palette("PuBu_r"))
plt.pie(job_exp,labels = job_exp.index, autopct = '%.1f%%', startangle = 90,textprops={'fontsize': 10},counterclock = False)
plt.axis('square')
#工作经验与薪水的关系
#以平均工资为基准
corr = df.pivot_table(index='学历',columns='经验',values='平均薪资') #df.pivot_table(index="city",columns="workYear",values="salary")
corr = corr[['不限', '应届生', '1-3年','3-5年', '5-10年', '10年以上']]
fig,ax = plt.subplots(figsize=(10,8))
sns.heatmap(corr,cmap="RdBu",center=20,annot=True,annot_kws={'fontsize':14})
plt.tick_params(axis='x', which='major', labelsize=16)
plt.tick_params(axis='y', which='major', labelsize=16,labelrotation=0)
plt.xlabel(""),plt.ylabel("")
#不同规模的公司在招人要求上的差异
company_size_map = {
"2000人以上": 6,
"500-2000人": 5,
"150-500人": 4,
"50-150人": 3,
"15-50人": 2,
"少于15人": 1
}
workYear_map = {
"10年以上": 6,
"5-10年": 5,
"3-5年": 4,
"1-3年": 3,
"应届生": 2,
"不限": 1
}
df["company_size"] = df["公司规模"].map(company_size_map)
df["work_year"] = df["经验"].map(workYear_map)
df_plot = df.sort_values(by="company_size",ascending=True)
# df_plot = df.loc[~df.work_year.isna()]
color_map = {
6:"#ff0000",
5:"#0000cd",
4:"#ffa500",
3:"#3c7f99",
2:"#c5b783",
1:"#d5fad3"
}
df_plot["color"] = df_plot.work_year.map(color_map)
df_plot.reset_index(drop=True,inplace=True)
def seed_scale_plot():
seeds=np.arange(6)+1
y=np.zeros(len(seeds),dtype=int)
s=seeds*100
colors=['#ff0000','#0000cd', '#ffa500','#3c7f99','#c5b783', '#d5fad3'][::-1]
fig,ax=plt.subplots(figsize=(12,1))
plt.scatter(seeds,y,s=s,c=colors,alpha=0.3)
plt.scatter(seeds,y,c=colors)
plt.box(False)
plt.grid(False)
plt.xticks(ticks=seeds,labels=list(workYear_map.keys())[::-1],fontsize=14)
plt.yticks(np.arange(1),labels=[' 经验:'],fontsize=16)
fig, ax = plt.subplots(figsize=(12, 8))
fig.text(x=0.03, y=0.92, s=' 不同规模公司的用人需求差异 ', fontsize=32,
weight='bold', color='white', backgroundcolor='#3c7f99')
plt.scatter(df_plot.平均薪资, df_plot["公司规模"], s=df_plot["work_year"]*100 ,alpha=0.35,c=df_plot["color"])
plt.scatter(df_plot.平均薪资, df_plot["公司规模"], c=df_plot["color"].values.tolist())
plt.tick_params(axis='both', which='both', length=0)
plt.tick_params(axis='both', which='major', labelsize=16)
ax.xaxis.grid(which='both', linewidth=0.75)
# plt.xticks(np.arange(0,61,10), [str(i)+"k" for i in range(0,150,10)])
plt.xlabel('平均薪资', fontsize=18)
plt.box(False)
seed_scale_plot()
b=[]
a=df['职位标签'].str.split('[').str[1].str.replace(']','').str.lower().str.replace("'",'').str.replace("/",',').str.strip()
for i in a:
if i !='':
c=i.split(',')
for j in c:
b.append(j.strip())
s=pd.Series(b)
tags=s.value_counts().to_dict()
#定义词云样式
wc = wordcloud.WordCloud(
background_color='white',
width=800,
height=400,
font_path='C:/Windows/Fonts/simhei.ttf', # 设置字体
max_words=200, # 最多显示词数
max_font_size=200) # 字号最大值
#生成词云图
wc.generate_from_frequencies(tags)
plt.imshow(wc) # 显示词云
plt.axis('off') # 关闭坐标轴