本次主要圍繞資料分析崗位的招聘情況, 進行一個簡單的資料分析
環境
win8, python3.7, pycharm, jupyter notebook
正文
1. 明确分析目的
了解資料分析崗位的最新招聘情況, 包括地區分布, 學曆要求, 經驗要求, 薪資水準等.
2. 資料收集
這裡借助爬蟲, 爬取招聘網站的招聘資訊, 進而分析出相關的薪資以及招聘要求.
2.1 目标站點分析
通過對目标站點的分析, 我們需要确定目标站點的請求方式, 以及網頁結構.
2.2 建立scrapy項目
1. 在cmd指令行視窗中任意路徑下執行以下代碼, 比如在"D:\python\Tests"目錄下建立zhaopin項目.
d:
cd D:\python\Tests
scrapy startproject zhaopin
2. 在完成了zhaopin項目建立之後, 接下來就是在zhaopin項目檔案夾中建立spider爬蟲主程式
cd zhaopin
scrapy genspider zhaopinSpider zhaopin.com
這樣就完成項目zhaopin的建立, 開始編寫我們的程式吧.
2.3 定義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() #職位福利
2.4 編寫爬蟲主程式
在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
2.5 儲存到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
2.6 配置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,
}
2.7 運作程式
建立main.py檔案, 并執行以下代碼
from scrapy import cmdline
cmdline.execute(\'scrapy crawl zhaopin\'.split())
這樣開始了資料爬取, 最終爬取到9000多條資料, 在分析這些資料之前, 先看看資料都是什麼樣, 進入資料概覽環節.
3. 資料概覽
3.1 讀取資料
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個浮點型)
3.2 描述性統計
由于我們所需資訊的資料類型都是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
可以看到還有機器學習開發講師, 人力銷售經理, 銀行客服等其他無效資料.
現在我們對資料有了大緻的認識, 下來我們開始資料預處理.
4. 資料預處理
4.1 資料清洗
資料清洗的目的是不讓有錯誤或有問題的資料進入加工過程, 其主要内容包括: 重複值, 缺失值以及空值的處理
4.1.1 删除重複值
如果資料中存在重複記錄, 而且重複數量較多時, 勢必會對結果造成影響, 是以我們應當首先處理重複值.
#删除資料表中的重複記錄, 并将删除後的資料表指派給zhaopin
zhaopin = df.drop_duplicates(inplace = False)
zhaopin.shape
(8927, 15)
對比之前的資料, 重複記錄1021條.
4.1.2 過濾無效資料
我們了解到職位名稱中存在無效資料, 我們對其的處理方式是過濾掉.
#篩選名稱中包含\'資料\'或\'分析\'或\'Data\'的職位
zhaopin = zhaopin[zhaopin.JobTitle.str.contains(\'.*?資料.*?|.*?分析.*?|.*?Data.*?\')]
zhaopin.shape
(7959, 15)
4.1.3 缺失值處理
在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
4.2 資料加工
由于現有的資料不能滿足我們的分析需求, 是以需要對現有資料表進行分列, 計算等等操作.
需要處理的特征有: Salary, Workplace
1. 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)
2. Workplace
對工作地區進行統一
#檢視工作地有哪些
zhaopin.Workplace.unique()
#檢視工作地點名字中包括省的有哪些, 結果顯示全部為xx省, 且其中不會出現市級地區名
zhaopin[zhaopin.Workplace.str.contains(\'省\')].Workplace.unique()
#将地區統一到市級
zhaopin[\'Workplace\'] = zhaopin.Workplace.str.split(\'-\', expand=True)[0]
3. 删除重複多餘資訊
zhaopin.drop([\'Salary\',\'Standard\', \'HighOrLow\'], axis = 1, inplace = True)
到目前為止, 我們對資料處理完成了, 接下來就是分析了.
5. 可視化分析
5.1 企業類型
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)
可以看出招聘中主要以民營企業, 合資企業和上市公司為主.
5.2 企業規模
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)
招聘資料分析崗位的公司規模主要以50-500人為主
5.3 地區
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()
可以看出北上廣深等經濟相對發達的地區, 對于資料分析崗位的需求量大.
參考自: https://blog.csdn.net/qq_41841569/article/details/82811153?utm_source=blogxgwz1
5.4 學曆和工作經驗
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)
學曆要求多以大學,大專為主, 工作經驗要求中無工作經驗要求為主, 可見招聘主要面向的是應屆畢業生.
5.4 薪資水準
1. 薪資與崗位需求關系
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)
可以看出, 随着需求量的減少, 薪資水準也有所降低.
2. 薪資與經驗關系
#求出各工作經驗對應的平均最高與平均最低薪資
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)
工作經驗越豐富, 薪資越高.
3. 薪資與學曆關系
#計算平均薪資
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. 北上廣深杭等經濟相對發達的地區對資料分析崗位的需求量大, 且薪資水準較高于其他地區; 學曆越高, 經驗越豐富對應的薪資水準也會增高.
以上便是我本次分享的内容,如有任何疑問,請在下方留言,或在公衆号【轉行學資料分析】聯系我!!!