用python分析招聘網站關於數據分析的工作崗位

前言

本文的文字及圖片來源於網絡,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯繫我們以作處理。

作者: Star_Zhao

PS:如有需要Python學習資料的小夥伴可以加點擊下方鏈接自行獲取http://t.cn/A6Zvjdun

本次主要圍繞數據分析崗位的招聘情況, 進行一個簡單的數據分析

環境

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, Field

class 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 zhaopinItem

class 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'] =JobTitle
        item['CompanyName'] =CompanyName
        item['CompanyNature'] =CompanyNature
        item['CompanySize'] = CompanySize
        item['IndustryField'] = IndustryField
        item['Salary'] =Salary
        item['Workplace'] = Workplace
        item['Workyear'] =Workyear
        item['Education'] =Education
        item['RecruitNumbers'] = RecruitNumbers
        item['ReleaseTime'] =ReleaseTime
        item['Language'] = Language
        item['Specialty'] = Specialty
        item['PositionAdvantage'] = PositionAdvantage
        yield item

編寫爬蟲主程序

在zhaopinSpider.py文件中編寫爬蟲主程序

import scrapy
from scrapy.selector import Selector
from scrapy.spiders import CrawlSpider
from scrapy.http import Request
from zhaopin.items import zhaopinItem

class 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'] =JobTitle
        item['CompanyName'] =CompanyName
        item['CompanyNature'] =CompanyNature
        item['CompanySize'] = CompanySize
        item['IndustryField'] = IndustryField
        item['Salary'] =Salary
        item['Workplace'] = Workplace
        item['Workyear'] =Workyear
        item['Education'] =Education
        item['RecruitNumbers'] = RecruitNumbers
        item['ReleaseTime'] =ReleaseTime
        item['Language'] = Language
        item['Specialty'] = Specialty
        item['PositionAdvantage'] = PositionAdvantage
        yield 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 pd

df = 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.1
    print(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. 北上廣深杭等經濟相對發達的地區對數據分析崗位的需求量大, 且薪資水平較高於其他地區; 學歷越高, 經驗越豐富對應的薪資水平也會增高.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章