用python分析招聘网站关于数据分析的工作岗位

2023-10-30 00:30

本文主要是介绍用python分析招聘网站关于数据分析的工作岗位,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

作者: Star_Zhao

PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获

python免费学习资料以及群交流解答点击即可加入


本次主要围绕数据分析岗位的招聘情况, 进行一个简单的数据分析

环境

win8, python3.7, pycharm, jupyter notebook

正文

明确分析目的

了解数据分析岗位的最新招聘情况, 包括地区分布, 学历要求, 经验要求, 薪资水平等.

数据收集
这里借助爬虫, 爬取招聘网站的招聘信息, 进而分析出相关的薪资以及招聘要求.

目标站点分析
通过对目标站点的分析, 我们需要确定目标站点的请求方式, 以及网页结构.

新建scrapy项目

在cmd命令行窗口中任意路径下执行以下代码, 比如在"D:\python\Tests"目录下新建zhaopin项目

d:
cd D:\python\Tests
scrapy startproject zhaopin

在完成了zhaopin项目创建之后, 接下来就是在zhaopin项目文件夹中新建spider爬虫主程序

cd zhaopin
scrapy genspider zhaopinSpider zhaopin.com

这样就完成项目zhaopin的创建, 开始编写我们的程序吧.

定义items

在items.py文件中定义需要爬取的招聘信息.

import scrapy
from scrapy.item import Item, Fieldclass zhaopinItem(Item):# define the fields for your item here like:# name = scrapy.Field()JobTitle = Field()                      #职位名称CompanyName = Field()                   #公司名称CompanyNature = Field()                 #公司性质CompanySize = Field()                   #公司规模IndustryField = Field()                 #所属行业Salary = Field()                        #薪水Workplace = Field()                     #工作地点Workyear = Field()                      #要求工作经验Education = Field()                     #要求学历RecruitNumbers = Field()                #招聘人数ReleaseTime = Field()                   #发布时间Language = Field()                      #要求语言Specialty = Field()                     #要求专业PositionAdvantage = Field()             #职位福利

编写爬虫主程序

在zhaopinSpider.py文件中编写爬虫主程序

import scrapy
from scrapy.selector import Selector
from scrapy.spiders import CrawlSpider
from scrapy.http import Request
from zhaopin.items import zhaopinItemclass ZhaoPinSpider(scrapy.Spider):name = "ZhaoPinSpider"allowed_domains = ['zhaopin.com']start_urls = ['https://xxxx.com/list/2,{0}.html?'.format(str(page)) for page in range(1, 217)]def parse(self, response):'''开始第一页:param response::return:'''yield Request(url = response.url,callback = self.parse_job_url,meta={},dont_filter= True)def parse_job_url(self, response):'''获取每页的职位详情页url:param response::return:'''selector = Selector(response)urls = selector.xpath('//div[@class="el"]/p/span')for url in urls:url = url.xpath('a/@href').extract()[0]yield Request(url = url,callback = self.parse_job_info,meta = {},dont_filter = True)def parse_job_info(self, response):'''解析工作详情页:param response::return:'''item = Job51Item()selector = Selector(response)JobTitle = selector.xpath('//div[@class="cn"]/h1/text()').extract()[0].strip().replace(' ','').replace(',',';')CompanyName = selector.xpath('//div[@class="cn"]/p[1]/a[1]/text()').extract()[0].strip().replace(',',';')CompanyNature = selector.xpath('//div[@class="tCompany_sidebar"]/div/div[2]/p[1]/text()').extract()[0].strip().replace(',',';')CompanySize = selector.xpath('//div[@class="tCompany_sidebar"]/div/div[2]/p[2]/text()').extract()[0].strip().replace(',',';')IndustryField = selector.xpath('//div[@class="tCompany_sidebar"]/div/div[2]/p[3]/text()').extract()[0].strip().replace(',',';')Salary = selector.xpath('//div[@class="cn"]/strong/text()').extract()[0].strip().replace(',',';')infos = selector.xpath('//div[@class="cn"]/p[2]/text()').extract()Workplace = infos[0].strip().replace('  ','').replace(',',';')Workyear = infos[1].strip().replace('  ','').replace(',',';')if len(infos) == 4:Education = ''RecruitNumbers = infos[2].strip().replace('  ', '').replace(',',';')ReleaseTime = infos[3].strip().replace('  ', '').replace(',',';')else:Education = infos[2].strip().replace('  ', '').replace(',',';')RecruitNumbers = infos[3].strip().replace('  ', '').replace(',',';')ReleaseTime = infos[4].strip().replace('  ', '').replace(',',';')if len(infos) == 7:Language, Specialty = infos[5].strip().replace('  ',''), infos[6].strip().replace('  ','').replace(',',';')elif len(infos) == 6:if (('英语' in infos[5]) or ('话' in infos[5])):Language, Specialty = infos[5].strip().replace('  ','').replace(',',';'), ''else:Language, Specialty = '', infos[5].strip().replace('  ','').replace(',',';')else:Language, Specialty = '', ''Welfare = selector.xpath('//div[@class="t1"]/span/text()').extract()PositionAdvantage = ';'.join(Welfare).replace(',', ';')item['JobTitle'] =JobTitleitem['CompanyName'] =CompanyNameitem['CompanyNature'] =CompanyNatureitem['CompanySize'] = CompanySizeitem['IndustryField'] = IndustryFielditem['Salary'] =Salaryitem['Workplace'] = Workplaceitem['Workyear'] =Workyearitem['Education'] =Educationitem['RecruitNumbers'] = RecruitNumbersitem['ReleaseTime'] =ReleaseTimeitem['Language'] = Languageitem['Specialty'] = Specialtyitem['PositionAdvantage'] = PositionAdvantageyield item

编写爬虫主程序

在zhaopinSpider.py文件中编写爬虫主程序

import scrapy
from scrapy.selector import Selector
from scrapy.spiders import CrawlSpider
from scrapy.http import Request
from zhaopin.items import zhaopinItemclass ZhaoPinSpider(scrapy.Spider):name = "ZhaoPinSpider"allowed_domains = ['zhaopin.com']start_urls = ['https://xxxx.com/list/2,{0}.html?'.format(str(page)) for page in range(1, 217)]def parse(self, response):'''开始第一页:param response::return:'''yield Request(url = response.url,callback = self.parse_job_url,meta={},dont_filter= True)def parse_job_url(self, response):'''获取每页的职位详情页url:param response::return:'''selector = Selector(response)urls = selector.xpath('//div[@class="el"]/p/span')for url in urls:url = url.xpath('a/@href').extract()[0]yield Request(url = url,callback = self.parse_job_info,meta = {},dont_filter = True)def parse_job_info(self, response):'''解析工作详情页:param response::return:'''item = Job51Item()selector = Selector(response)JobTitle = selector.xpath('//div[@class="cn"]/h1/text()').extract()[0].strip().replace(' ','').replace(',',';')CompanyName = selector.xpath('//div[@class="cn"]/p[1]/a[1]/text()').extract()[0].strip().replace(',',';')CompanyNature = selector.xpath('//div[@class="tCompany_sidebar"]/div/div[2]/p[1]/text()').extract()[0].strip().replace(',',';')CompanySize = selector.xpath('//div[@class="tCompany_sidebar"]/div/div[2]/p[2]/text()').extract()[0].strip().replace(',',';')IndustryField = selector.xpath('//div[@class="tCompany_sidebar"]/div/div[2]/p[3]/text()').extract()[0].strip().replace(',',';')Salary = selector.xpath('//div[@class="cn"]/strong/text()').extract()[0].strip().replace(',',';')infos = selector.xpath('//div[@class="cn"]/p[2]/text()').extract()Workplace = infos[0].strip().replace('  ','').replace(',',';')Workyear = infos[1].strip().replace('  ','').replace(',',';')if len(infos) == 4:Education = ''RecruitNumbers = infos[2].strip().replace('  ', '').replace(',',';')ReleaseTime = infos[3].strip().replace('  ', '').replace(',',';')else:Education = infos[2].strip().replace('  ', '').replace(',',';')RecruitNumbers = infos[3].strip().replace('  ', '').replace(',',';')ReleaseTime = infos[4].strip().replace('  ', '').replace(',',';')if len(infos) == 7:Language, Specialty = infos[5].strip().replace('  ',''), infos[6].strip().replace('  ','').replace(',',';')elif len(infos) == 6:if (('英语' in infos[5]) or ('话' in infos[5])):Language, Specialty = infos[5].strip().replace('  ','').replace(',',';'), ''else:Language, Specialty = '', infos[5].strip().replace('  ','').replace(',',';')else:Language, Specialty = '', ''Welfare = selector.xpath('//div[@class="t1"]/span/text()').extract()PositionAdvantage = ';'.join(Welfare).replace(',', ';')item['JobTitle'] =JobTitleitem['CompanyName'] =CompanyNameitem['CompanyNature'] =CompanyNatureitem['CompanySize'] = CompanySizeitem['IndustryField'] = IndustryFielditem['Salary'] =Salaryitem['Workplace'] = Workplaceitem['Workyear'] =Workyearitem['Education'] =Educationitem['RecruitNumbers'] = RecruitNumbersitem['ReleaseTime'] =ReleaseTimeitem['Language'] = Languageitem['Specialty'] = Specialtyitem['PositionAdvantage'] = PositionAdvantageyield item

保存到csv文件

通过pipelines项目管道保存至csv文件

class Job51Pipeline(object):def process_item(self, item, spider):with open(r'D:\Data\ZhaoPin.csv','a', encoding = 'gb18030') as f:job_info = [item['JobTitle'], item['CompanyName'], item['CompanyNature'], item['CompanySize'], item['IndustryField'], item['Salary'], item['Workplace'], item['Workyear'], item['Education'], item['RecruitNumbers'], item['ReleaseTime'],item['Language'],item['Specialty'],item['PositionAdvantage'],'\n']f.write(",".join(job_info))return item

配置setting

设置用户代理, 下载延迟0.5s, 关闭cookie追踪, 调用pipelines

USER_AGENT = 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
DOWNLOAD_DELAY = 0.5
COOKIES_ENABLED = False
ITEM_PIPELINES = {'job51.pipelines.Job51Pipeline': 300,
}

运行程序

新建main.py文件, 并执行以下代码

from scrapy import cmdline
cmdline.execute('scrapy crawl zhaopin'.split())

这样开始了数据爬取, 最终爬取到9000多条数据, 在分析这些数据之前, 先看看数据都是什么样, 进入数据概览环节.

数据概览

读取数据

import pandas as pddf = pd.read_csv(r'D:\aPython\Data\DataVisualization\shujufenxishiJob51.csv')
#由于原始数据中没有字段, 需要为其添加字段
df.columns = ['JobTitle','CompanyName','CompanyNature','CompanySize','IndustryField','Salary','Workplace','Workyear','Education','RecruitNumbers', 'ReleaseTime','Language','Specialty','PositionAdvantage']
df.info()

抛出异常: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbd in position 0: invalid start byte

  • 解决办法; 用Notepad++将编码转换为utf-8 bom格式

转换之后, 再次执行

抛出异常: ValueError: Length mismatch: Expected axis has 15 elements, new values have 14 elements

  • 解决办法: 在列表[‘JobTitle…PositionAdvantage’]后面追加’NNN’, 从而补齐15个元素.

追加之后, 再次执行, 执行结果为:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 9948 entries, 0 to 9947
Data columns (total 15 columns):
JobTitle             9948 non-null object
CompanyName          9948 non-null object
CompanyNature        9948 non-null object
CompanySize          9948 non-null object
IndustryField        9948 non-null object
Salary               9948 non-null object
Workplace            9948 non-null object
Workyear             9948 non-null object
Education            7533 non-null object
RecruitNumbers       9948 non-null object
ReleaseTime          9948 non-null object
Language             901 non-null object
Specialty            814 non-null object
PositionAdvantage    8288 non-null object
NNN                  0 non-null float64
dtypes: float64(1), object(14)
memory usage: 1.1+ MB

可以了解到的信息: 目前的数据维度9948行X15列, Education, Language, Specialty, PositionAdvantage有不同程度的缺失(NNN是最后添加, 仅仅是用来补齐15元素), 14个python对象(1个浮点型)

描述性统计

由于我们所需信息的数据类型都是python对象, 故使用以下代码

#注意是大写的字母o
df.describe(include=['O'])

从以下信息(公司名称部分我没有截图)中可以得到:

职位名称中’数据分析师’最多, 多为民营公司, 公司规模150-500人最多, 行业领域金融/投资/证券最多, 薪资中6-8千/月最多, 大多对工作经验没有要求, 学历要求多为本科, 多数均招1人等信息.
在这里插入图片描述
职位名称的种类就有4758种, 他们都是我们本次分析的数据分析师岗位吗, 先来确认下:

zhaopin.JobTitle.unique()
array(['零基础免费培训金融外汇数据分析师', '数据分析师(周末双休+上班舒适)', '数据分析师', ...,'数据分析实习(J10635)', '数据分析实习(J10691)', '数据分析实习(J10713)'], dtype=object)

这仅仅显示了职位名称中的一部分,而且还都符合要求, 换种思路先看20个

JobTitle = zhaopin.groupby('JobTitle', as_index=False).count()
JobTitle.JobTitle.head(20)
0                             (AI)机器学习开发工程师讲师
1                           (ID67391)美资公司数据分析
2                           (ID67465)美资公司数据分析
3             (ID67674)500强法资汽车制造商数据分析专员(6个月)
4                 (ID67897)知名500强法资公司招聘数据分析专员
5                         (Senior)DataAnalyst
6                           (免费培训)数据分析师+双休+底薪
7            (实习职位)BusinessDataAnalyst/业务数据分析
8                                   (急)人力销售经理
9                               (提供食宿)银行客服+双休
10    (日语)股票数据分析员/EquityDataAnalyst-Japanese/
11     (越南语)股票数据分析员/EquityDataAnalyst-Vietnam
12                           (跨境电商)产品专员/数据分析师
13       (韩语)股票数据分析员/EquityDataAnalyst-Korean
14                                    ***数据分析
15                               -数据分析师助理/实习生
16                      -数据分析师助理/统计专员+双休五险+住宿
17                        -无销售不加班金融数据分析师月入10k
18                          -金融数据分析师助理6k-1.5w
19                             -金融数据分析师双休岗位分红
Name: JobTitle, dtype: object

可以看到还有机器学习开发讲师, 人力销售经理, 银行客服等其他无效数据.

现在我们对数据有了大致的认识, 下来我们开始数据预处理.

数据预处理

数据清洗

数据清洗的目的是不让有错误或有问题的数据进入加工过程, 其主要内容包括: 重复值, 缺失值以及空值的处理

删除重复值

如果数据中存在重复记录, 而且重复数量较多时, 势必会对结果造成影响, 因此我们应当首先处理重复值.

#删除数据表中的重复记录, 并将删除后的数据表赋值给zhaopin
zhaopin = df.drop_duplicates(inplace = False)
zhaopin.shape
(8927, 15)

对比之前的数据, 重复记录1021条.

过滤无效数据

我们了解到职位名称中存在无效数据, 我们对其的处理方式是过滤掉.

#筛选名称中包含'数据'或'分析'或'Data'的职位
zhaopin = zhaopin[zhaopin.JobTitle.str.contains('.*?数据.*?|.*?分析.*?|.*?Data.*?')]
zhaopin.shape
(7959, 15)

缺失值处理

在pandas中缺失值为NaN或者NaT, 其处理方式有多种:

  1. 利用均值等集中趋势度量填充

  2. 利用统计模型计算出的值填充

  3. 保留缺失值

  4. 删除缺失值

#计算每个特征中缺失值个数
zhaopin.isnull().sum()
JobTitle                0
CompanyName             0
CompanyNature           0
CompanySize             0
IndustryField           0
Salary                  0
Workplace               0
Workyear                0
Education            1740
RecruitNumbers          0
ReleaseTime             0
Language             7227
Specialty            7244
PositionAdvantage    1364
NNN                  7959
dtype: int64
  • Education: 缺失值占比1740/7959 = 21.86%, 缺失很有可能是"不限学历", 我们就用"不限学历"填充
zhaopin.Education.fillna('不限学历', inplace=True)
  • Language: 缺失值占比7227/7959 = 90.80%, 缺失太多, 删除特征

  • Specialty: 缺失值占比7244/7959 = 91.02%, 同样缺失很多, 删除

zhaopin.drop(['Specialty','Language'], axis=1, inplace = True)
  • PositionAdvantage: 缺失占比1364/7959 = 17.14%, 选用众数中的第一个’五险一金’填充
zhaopin.PositionAdvantage.fillna(zhaopin.PositionAdvantage.mode()[0], inplace = True)
  • NNN: 没有任何意义, 直接删除
zhaopin.drop(["NNN"], axis=1, inplace = True)

最后, 检查缺失值是否处理完毕

zhaopin.isnull().sum()
JobTitle             0
CompanyName          0
CompanyNature        0
CompanySize          0
IndustryField        0
Salary               0
Workplace            0
Workyear             0
Education            0
RecruitNumbers       0
ReleaseTime          0
PositionAdvantage    0
dtype: int64

数据加工

由于现有的数据不能满足我们的分析需求, 因此需要对现有数据表进行分列, 计算等等操作.

需要处理的特征有: Salary, Workplace

Salary

将薪资分为最高薪资和最低薪资, 另外了解到薪资中单位有元/小时, 元/天, 万/月, 万/年, 千/月, 统一将其转化为千/月

import re
#将5种单元进行编号
zhaopin['Standard'] = np.where(zhaopin.Salary.str.contains('元.*?小时'), 0, np.where(zhaopin.Salary.str.contains('元.*?天'), 1,np.where(zhaopin.Salary.str.contains('千.*?月'), 2, np.where(zhaopin.Salary.str.contains('万.*?月'), 3, 4))))
#用'-'将Salary分割为LowSalary和HighSalary
SalarySplit = zhaopin.Salary.str.split('-', expand = True)
zhaopin['LowSalary'], zhaopin['HighSalary'] = SalarySplit[0], SalarySplit[1]
#Salary中包含'以上', '以下'或者两者都不包含的进行编号
zhaopin['HighOrLow'] = np.where(zhaopin.LowSalary.str.contains('以.*?下'), 0, np.where(zhaopin.LowSalary.str.contains('以.*?上'), 2, 1))
#匹配LowSalary中的数字, 并转为浮点型
Lower = zhaopin.LowSalary.apply(lambda x: re.search('(\d+\.?\d*)', x).group(1)).astype(float)
#对LowSalary中HighOrLow为1的部分进行单位换算, 全部转为'千/月'
zhaopin.LowSalary = np.where(((zhaopin.Standard==0)&(zhaopin.HighOrLow==1)), Lower*8*21/1000,np.where(((zhaopin.Standard==1)&(zhaopin.HighOrLow==1)), Lower*21/1000,np.where(((zhaopin.Standard==2)&(zhaopin.HighOrLow==1)), Lower,np.where(((zhaopin.Standard==3)&(zhaopin.HighOrLow==1)), Lower*10,np.where(((zhaopin.Standard==4)&(zhaopin.HighOrLow==1)), Lower/12*10,Lower)))))#对HighSalary中的缺失值进行填充, 可以有效避免匹配出错.
zhaopin.HighSalary.fillna('0千/月', inplace =True)
#匹配HighSalary中的数字, 并转为浮点型
Higher = zhaopin.HighSalary.apply(lambda x: re.search('(\d+\.?\d*).*?', str(x)).group(1)).astype(float)
#对HighSalary中HighOrLow为1的部分完成单位换算, 全部转为'千/月'
zhaopin.HighSalary = np.where(((zhaopin.Standard==0)&(zhaopin.HighOrLow==1)),zhaopin.LowSalary/21*26,np.where(((zhaopin.Standard==1)&(zhaopin.HighOrLow==1)),zhaopin.LowSalary/21*26,np.where(((zhaopin.Standard==2)&(zhaopin.HighOrLow==1)), Higher,np.where(((zhaopin.Standard==3)&(zhaopin.HighOrLow==1)), Higher*10,np.where(((zhaopin.Standard==4)&(zhaopin.HighOrLow==1)), Higher/12*10,np.where(zhaopin.HighOrLow==0, zhaopin.LowSalary, zhaopin.LowSalary))))))
#查看当HighOrLow为0时, Standard都有哪些, 输出为2, 4
zhaopin[zhaopin.HighOrLow==0].Standard.unique()   
#完成HighOrLow为0时的单位换算
zhaopin.loc[(zhaopin.HighOrLow==0)&(zhaopin.Standard==2), 'LowSalary'] = zhaopin[(zhaopin.HighOrLow==0)&(zhaopin.Standard==2)].HighSalary.apply(lambda x: 0.8*x)
zhaopin.loc[(zhaopin.HighOrLow==0)&(zhaopin.Standard==4), 'HighSalary'] = zhaopin[(zhaopin.HighOrLow==0)&(zhaopin.Standard==4)].HighSalary.apply(lambda x: x/12*10)
zhaopin.loc[(zhaopin.HighOrLow==0)&(zhaopin.Standard==4), 'LowSalary'] = zhaopin[(zhaopin.HighOrLow==0)&(zhaopin.Standard==4)].HighSalary.apply(lambda x: 0.8*x)
#查看当HighOrLow为2时, Srandard有哪些, 输出为4
zhaopin[zhaopin.HighOrLow==2].Standard.unique() 
#完成HighOrLow为2时的单位换算
zhaopin.loc[zhaopin.HighOrLow==2, 'LowSalary']  = zhaopin[zhaopin.HighOrLow==2].HighSalary.apply(lambda x: x/12*10)
zhaopin.loc[zhaopin.HighOrLow==2, 'HighSalary'] = zhaopin[zhaopin.HighOrLow==2].LowSalary.apply(lambda x: 1.2*x)zhaopin.LowSalary , zhaopin.HighSalary = zhaopin.LowSalary.apply(lambda x: '%.1f'%x), zhaopin.HighSalary.apply(lambda x: '%.1f'%x)

Workplace

对工作地区进行统一

#查看工作地有哪些
zhaopin.Workplace.unique()
#查看工作地点名字中包括省的有哪些, 结果显示全部为xx省, 且其中不会出现市级地区名
zhaopin[zhaopin.Workplace.str.contains('省')].Workplace.unique()
#将地区统一到市级
zhaopin['Workplace'] = zhaopin.Workplace.str.split('-', expand=True)[0]

删除重复多余信息

zhaopin.drop(['Salary','Standard', 'HighOrLow'], axis = 1, inplace = True)

到目前为止, 我们对数据处理完成了, 接下来就是分析了.

可视化分析

企业类型

import matplotlib
import matplotlib.pyplot as plt
CompanyNature_Count = zhaopin.CompanyNature.value_counts()
#设置中文字体
font = {'family': 'SimHei'}
matplotlib.rc('font', **font)
fig = plt.figure(figsize = (8, 8))
#绘制饼图, 参数pctdistance表示饼图内部字体离中心距离, labeldistance则是label的距离, radius指饼图的半径
patches, l_text, p_text = plt.pie(CompanyNature_Count, autopct = '%.2f%%', pctdistance = 0.6, labels = CompanyNature_Count.index, labeldistance=1.1, radius = 1)
m , n= 0.02, 0.028
for t in l_text[7: 11]:t.set_y(m)m += 0.1
for p in p_text[7: 11]:p.set_y(n)n += 0.1
plt.title('数据分析岗位中各类型企业所占比例', fontsize=24)

可以看出招聘中主要以民营企业, 合资企业和上市公司为主.
在这里插入图片描述
企业规模

CompanySize_Count = zhaopin.CompanySize.value_counts()
index, bar_width= np.arange(len(CompanySize_Count)), 0.6
fig = plt.figure(figsize = (8, 6))
plt.barh(index*(-1)+bar_width, CompanySize_Count, tick_label = CompanySize_Count.index, height = bar_width)
#添加数据标签
for x,y in enumerate(CompanySize_Count):plt.text(y+0.1, x*(-1)+bar_width, '%s'%y, va = 'center')
plt.title('数据分析岗位各公司规模总数分布条形图', fontsize = 24)

在这里插入图片描述
地区

from pyecharts import Geo
from collections import Counter
#统计各地区出现次数, 并转换为元组的形式
data = Counter(place).most_common()
#生成地理坐标图
geo =Geo("数据分析岗位各地区需求量", title_color="#fff", title_pos="center", width=1200, height=600, background_color='#404a59')
attr, value =geo.cast(data)
#添加数据点
geo.add('', attr, value, visual_range=[0, 100],visual_text_color='#fff', symbol_size=5, is_visualmap=True, is_piecewise=True)
geo.show_config()
geo.render()

可以看出北上广深等经济相对发达的地区, 对于数据分析岗位的需求量大.
在这里插入图片描述
学历和工作经验

fig, ax = plt.subplots(1, 2, figsize = (18, 8))
Education_Count = zhaopin.Education.value_counts()
Workyear_Count = zhaopin.Workyear.value_counts()
patches, l_text, p_text = ax[0].pie(Education_Count, autopct = '%.2f%%', labels = Education_Count.index )
m = -0.01
for t in l_text[6:]:t.set_y(m)m += 0.1print(t)
for p in p_text[6:]:p.set_y(m)m += 0.1
ax[0].set_title('数据分析岗位各学历要求所占比例', fontsize = 24)
index, bar_width = np.arange(len(Workyear_Count)), 0.6
ax[1].barh(index*(-1) + bar_width, Workyear_Count, tick_label = Workyear_Count.index, height = bar_width)
ax[1].set_title('数据分析岗位工作经验要求', fontsize= 24)

学历要求多以本科,大专为主, 工作经验要求中无工作经验要求为主, 可见招聘主要面向的是应届毕业生.在这里插入图片描述
薪资水平

薪资与岗位需求关系

fig = plt.figure(figsize = (9,7))
#转换类型为浮点型
zhaopin.LowSalary, zhaopin.HighSalary = zhaopin.LowSalary.astype(float), zhaopin.HighSalary.astype(float)
#分别求各地区平均最高薪资, 平均最低薪资
Salary = zhaopin.groupby('Workplace', as_index = False)['LowSalary', 'HighSalary'].mean()#分别求各地区的数据分析岗位数量,并降序排列 
Workplace = zhaopin.groupby('Workplace', as_index= False)['JobTitle'].count().sort_values('JobTitle', ascending = False)#合并数据表
Workplace = pd.merge(Workplace, Salary, how = 'left', on = 'Workplace')#用前20名进行绘图
Workplace = Workplace.head(20)
plt.bar(Workplace.Workplace, Workplace.JobTitle, width = 0.8, alpha = 0.8)
plt.plot(Workplace.Workplace, Workplace.HighSalary*1000, '--',color = 'g', alpha = 0.9, label='平均最高薪资')
plt.plot(Workplace.Workplace, Workplace.LowSalary*1000, '-.',color = 'r', alpha = 0.9, label='平均最低薪资')
#添加数据标签
for x, y in enumerate(Workplace.HighSalary*1000):plt.text(x, y, '%.0f'%y, ha = 'left', va='bottom')
for x, y in enumerate(Workplace.LowSalary*1000):plt.text(x, y, '%.0f'%y, ha = 'right', va='bottom')
for x, y in enumerate(Workplace.JobTitle):plt.text(x, y, '%s'%y, ha = 'center', va='bottom')
plt.legend()
plt.title('数据分析岗位需求量排名前20地区的薪资水平状况', fontsize = 20)

可以看出, 随着需求量的减少, 薪资水平也有所降低.
在这里插入图片描述
薪资与经验关系

#求出各工作经验对应的平均最高与平均最低薪资
Salary_Year = zhaopin.groupby('Workyear', as_index = False)['LowSalary', 'HighSalary'].mean()
#求平均薪资
Salary_Year['Salary'] = (Salary_Year.LowSalary.add(Salary_Year.HighSalary)).div(2)
#转换列, 得到想要的顺序
Salary_Year.loc[0], Salary_Year.loc[6] = Salary_Year.loc[6], Salary_Year.loc[0]
#绘制条形图
plt.barh(Salary_Year.Workyear, Salary_Year.Salary, height = 0.6)
for x, y in enumerate(Salary_Year.Salary):plt.text(y+0.1,x, '%.2f'%y, va = 'center')
plt.title('各工作经验对应的平均薪资水平(单位:千/月)', fontsize = 20)

工作经验越丰富, 薪资越高.
在这里插入图片描述
薪资与学历关系

#计算平均薪资
Salary_Education = zhaopin.groupby('Education', as_index = False)['LowSalary', 'HighSalary'].mean()
Salary_Education['Salary'] = Salary_Education.LowSalary.add(Salary_Education.HighSalary).div(2)
Salary_Education = Salary_Education.sort_values('Salary', ascending = True)
#绘制柱形图
plt.bar(Salary_Education.Education, Salary_Education.Salary, width = 0.6)
for x,y in enumerate(Salary_Education.Salary):plt.text(x, y, '%.2f'%y, ha = 'center', va='bottom')
plt.title('各学历对应的平均工资水平(单位:千/月)', fontsize = 20)

学历越高, 对应的薪资水平越高
在这里插入图片描述

总结

  1. 数据分析岗位中企业类型以民营企业, 合资企业和上市公司为主, 企业规模多为50-500人.

  2. 数据分析岗位的学历要求以本科,大专为主, 经验中无工作经验占多数, 可见主要面向的是应届毕业生.

  3. 北上广深杭等经济相对发达的地区对数据分析岗位的需求量大, 且薪资水平较高于其他地区; 学历越高, 经验越丰富对应的薪资水平也会增高.

这篇关于用python分析招聘网站关于数据分析的工作岗位的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/304430

相关文章

Go标准库常见错误分析和解决办法

《Go标准库常见错误分析和解决办法》Go语言的标准库为开发者提供了丰富且高效的工具,涵盖了从网络编程到文件操作等各个方面,然而,标准库虽好,使用不当却可能适得其反,正所谓工欲善其事,必先利其器,本文将... 目录1. 使用了错误的time.Duration2. time.After导致的内存泄漏3. jsO

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

Python Websockets库的使用指南

《PythonWebsockets库的使用指南》pythonwebsockets库是一个用于创建WebSocket服务器和客户端的Python库,它提供了一种简单的方式来实现实时通信,支持异步和同步... 目录一、WebSocket 简介二、python 的 websockets 库安装三、完整代码示例1.

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

Python使用自带的base64库进行base64编码和解码

《Python使用自带的base64库进行base64编码和解码》在Python中,处理数据的编码和解码是数据传输和存储中非常普遍的需求,其中,Base64是一种常用的编码方案,本文我将详细介绍如何使... 目录引言使用python的base64库进行编码和解码编码函数解码函数Base64编码的应用场景注意

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

Python+PyQt5实现多屏幕协同播放功能

《Python+PyQt5实现多屏幕协同播放功能》在现代会议展示、数字广告、展览展示等场景中,多屏幕协同播放已成为刚需,下面我们就来看看如何利用Python和PyQt5开发一套功能强大的跨屏播控系统吧... 目录一、项目概述:突破传统播放限制二、核心技术解析2.1 多屏管理机制2.2 播放引擎设计2.3 专

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2