資料分析崗位需求分析報告
1.前言
"大資料",這個字眼是近幾年比較火的一個名詞,資料的價值正在各行各業發揮著越來越大的價值,銷售行業通過銷售資料的分析,對客戶行為的畫像(給客戶貼標籤),指定相應的銷售策略提高銷售業績;以淘寶、京東商城等為代表的電商平臺通過客戶的購買行為,自動推薦符合客戶"需求"的產品;以信貸公司、銀行業等為主的金融公司通過分析客戶的信用評估,對客戶進行分級"打分",優先放款給"優質客戶",等等。似乎,正在以一種偶像般的存在,影響著每一個人、每一個行業,鼓動著每一個"蠢蠢欲動"的人。然而,大多數的時候這個名詞都被人誤解或者過分渲染了。"管它黑貓白貓,能抓住老鼠的都是好貓",換句話說:管它是大資料還是一般資料,能支援經營管理決策的都是好資料。所以,從企業自身而言,首要任務是充分利用自身資料,推動經營決策。而對於個人,應該充分結合實際情況,認真做好自己的職業規劃,而不是盲目跟風。結合自身的優勢,忠於企業和個人,盡最大限度的發揮自身價值為企業和社會貢獻出自己的一份力量。
本文筆者以一名正在轉行路上的身份,爬取了拉勾網資料分析職位的前100頁,共計1500條的招聘資訊,通過資料探勘,統計建模等方法,對資料分析職位特點及現狀做一個分析。
2.用到的工具
Spyder3.6
requests: 下載網頁
pandas:資料分析庫
numpy:陣列操作
matplotlib:繪圖
wordcloud、jieba:生成中文詞雲
rcParams:使繪圖能顯示中文字型
3.網頁結構分析
開啟搜狗高速瀏覽器,在拉勾網首頁搜尋的“資料分析”職位,滑鼠右擊檢視網頁原始檔,通過搜尋相關關鍵字可以發現, 職位資訊並不在原始碼裡。進一步抓包分析,點選審查元素(快捷鍵F12),可以發現職位資訊隱藏於JSON的檔案裡,結合資料格式,我們選擇用字典方法直接讀取資料。
執行程式得到如下資料:(程式碼見附錄)
因為檔案是csv格式檔案,建議用notepad或者WPS開啟(直接用office Excel不支援會出現亂碼)
4.資料預處理
為了保證後續分析的正常進行,需要對資料進行預處理。觀看資料可以得出如下操作步驟:
(1).資料分析職位中可能存在"實習生崗位",需要對其進行剔除。
(2).表中的"工作經驗"屬於範圍值,在此對其進行平均化處理。
(3).表中的"工資"也屬於範圍,在此也對其進行平均化處理,取中間值。
(4).刪除冗餘列,儲存到新的表格。
處理後得到如下資料表:(程式碼見附錄)
5.資料分析崗位分佈情況
5.1公司的城市分佈
由下圖可以看出:北京資料分析師崗位需求佔據了47.2%,上海地區21.9%,杭州地區9.6%,深圳地區8.6%,廣州地區,南京地區等地區的崗位需=需求量緊隨其後,基本上主要集中在一線城市和強二線城市中。
5.2公司的融資情況
下圖中可以看出,在招聘公司中:不需要融資的公司、上市公司、C輪融資階段的公司對資料分析師的崗位需求量最大,A輪、D輪、B輪、未融資等階段的公司緊隨其後。說明發展相對成熟,穩健的公司有更大可能性需要資料分析崗位的人才。
5.3崗位福利狀況
針對爬取的拉勾網資料的職位福利,,進行jieba分詞,並製作詞雲。出現頻率最高的依次是:彈性工作、發展空間、氛圍、工資等,從圖中詞頻的頻率可以看出,招聘崗位更注重職位的發展與員工的體驗,其次是工資水平與各類獎金。
6.資料分析崗位的發展狀況
6.1各城市平均薪資待遇
從圖中可以看出各城市平均工資最高的是北京20.1469,其次上海、杭州、深圳、廣州、南京、緊隨其後,其中長春的平均工資值得商榷,因為從上資料分析師崗位需求上來看,長春的資料分析師需求量非常小。在此處作為異常值處理。
6.2不同融資階段平均工資待遇
由下圖可以看出,不同融資階段公司對資料分析師給出的平均薪資略有不同,D輪、C輪、B輪、上市公司平均工資相對較大y一些。
7.資料分析師崗位招聘要求
7.1統計量描述
count 1469.000000
mean 3.167461
std 1.909803
min 0.000000
25% 2.000000
50% 4.000000
75% 4.000000
max 7.500000
工作年限平均值為3.167年,中位數是4年,大致可以說明企業要求有一定工作經驗的佔據多數。
mean 17.497958
std 8.431887
min 1.500000
25% 11.500000
50% 15.000000
75% 22.500000
max 80.000000
平均工作為8.431k,中位數為15k,大致可以看出,地區間存在兩級分化比較嚴重,崗位偏集中,工資偏兩極。下面作進一步分析。
7.2學歷與職位需求
由下圖比例可以看出,招聘單位85.7%要求入門是本科學歷,本科學歷資料分析崗市場需求量第一,大專學歷7.3%排名第二,相應的碩士學歷反而要求不高。也從間接的方面看出,公司可能更看重資料分析的經驗能力。
7.3學歷水平與工資
可以看出,資料分析師崗位學歷水平與平均薪資成正比關係,學歷越高,工資越高,碩士工資20k左右,本科平均工資17.5k左右,相差不大,但是大專學歷平均工資卻只有10k左右。差距較為明顯。平時好好學習還是有一定好處的(哈哈)。
7.4工作經驗與職位需求
表中可以看出工作經驗與職位需求成正比關係。3-5年和1-3年的資料分析師崗位需求量最大,前者佔比43.6%,後者佔比35.1%,說明資料分析崗位更看重資料分析經驗。企業所需培養的成本相對較小,所以企業更願意招攬此類人才。相對應的,經驗過少和5-10年的工作者是兩個極端,無工作經驗或者1年以下的求職者培養起來需要更大的成本。後者則需要更大的招聘成本。
7.5工作經驗與工資
由下圖可看出:工作經驗與平均工資水平成正比,相關工作年限越長,平均工資也越高。
8.附錄(詳細程式碼):
8.1資料特徵部分程式碼
import pandas as pd
import matplotlib.pyplot as plt
# 讀取資料
df = pd.read_csv('D:/baogao/lagou_data2.csv', encoding = 'utf-8') #讀取資料,編碼處理
#1.統計量描述
fb=df['經驗'].describe()
fb2=df['平均工資'].describe()
print(fb,fb2) #輸出統計量
plt.rcParams['font.sans-serif']=['SimHri'] #用來正常顯示中文標籤
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] ## 指定預設字型:解決plot不能顯示中文問題
#2.繪製城市分佈的餅圖(取前10)
count = df['城市'].value_counts()
count=count[0:10] #取序列前10的城市繪製餅圖
plt.pie(count, labels = count.keys() ,labeldistance=1.4,autopct='%2.1f%%')
plt.axis('equal') # 使餅圖為正圓形
plt.legend(loc='upper left', bbox_to_anchor=(-0.1, 1)) #新增圖例,並設定圖例位置
plt.savefig('location.jpg')
plt.show()
#2.繪製城市分佈的柱狀圖,柱狀圖繪製前15名
count1 = df['城市'].value_counts()
count1=count1[0:15] #取序列前15的城市繪製柱狀圖
plt.bar(count1.keys(),count1)
plt.savefig('城市柱狀圖15名.jpg')
plt.show()
#3.繪製融資階段柱狀圖
count2 = df['融資階段'].value_counts()
plt.bar(count2.keys(),count2)
plt.savefig('融資階段分佈.jpg')
plt.show()
#4.繪製學歷與職位需求的關係
count3 = df['學歷要求'].value_counts()
plt.pie(count3, labels = count3.keys() ,labeldistance=1.4,autopct='%2.1f%%')
plt.axis('equal') # 使餅圖壓縮為正圓形
plt.legend(loc='upper left', bbox_to_anchor=(-0.1, 1)) #新增圖例,並設定圖例位置
plt.savefig('學歷與職位需求關係.jpg')
plt.show()
#5.繪製工作經驗與職位需求的柱狀圖
count4 = df['工作經驗'].value_counts()
plt.bar(count4.keys(),count4)
plt.savefig('工作經驗與職位需求.jpg')
plt.show()
8.2資料預處理部分程式碼
#資料預處理
import pandas as pd
# 讀取資料
df = pd.read_csv('D:/baogao/lagou_data.csv', encoding = 'utf-8')
# 資料清洗,剔除實習崗位
df.drop(df[df['職位名稱'].str.contains('實習')].index, inplace=True)
# 正則表示式將csv檔案字串轉化為列表,再取區間的均值
pattern = '\d+'
df['工作年限'] = df['工作經驗'].str.findall(pattern)
avg_work_year = []
for i in df['工作年限']:
# 如果工作經驗為'不限'或'應屆畢業生',那麼匹配值為空,工作年限為0
if len(i) == 0:
avg_work_year.append(0)
# 如果匹配值為一個數值,那麼返回該數值
elif len(i) == 1:
avg_work_year.append(int(''.join(i)))
# 如果匹配值為一個區間,那麼取平均值
else:
num_list = [int(j) for j in i]
avg_year = sum(num_list)/2
avg_work_year.append(avg_year)
df['經驗'] = avg_work_year
df=df.drop('工作年限',1) #刪除工作年限資料列(冗餘資料)
df['salary'] = df['工資'].str.findall(pattern) #字串轉化為列表,取區間平均值作為薪資
avg_salary = []
for k in df['salary']:
int_list = [int(n) for n in k]
avg_wage = (int_list[1]+int_list[0])/2
avg_salary.append(avg_wage)
df['平均工資']=avg_salary
df= df.drop('salary',1) #刪除salary資料列(冗餘資料)
df= df.drop('工資',1) ##刪除工資資料列(冗餘資料)
# 將清洗後的資料儲存,以便後續使用
df.to_csv('lagou_data2.csv', index = False)
8.3繪製詞雲圖
#繪製詞雲圖
import numpy as np
from PIL import Image
import jieba
from wordcloud import WordCloud,ImageColorGenerator,STOPWORDS
import matplotlib.pyplot as plt
df = pd.read_csv('D:/baogao/lagou_data2.csv', encoding = 'utf-8') #讀取資料並編碼處理
text = ''
for line in df['職位福利']:
text += line #使用jieba模組將字串分割為單詞列表
f=open("D:/baogao/職位福利.txt","a+") #以追加的方式建立一個文字檔案
f.write(text) #寫人職位福利文字內容
f.write("\n") # 寫完通過\n進行換行
f.close() #關閉文件
from random import randint
#封裝改變顏色函式
def random_color_func(word=None, font_size=None, position=None, orientation=None, font_path=None, random_state=None):
h = randint(120,250)
s = int(100.0 * 255.0 / 255.0)
l = int(100.0 * float(randint(60, 120)) / 255.0)
return "hsl({}, {}%, {}%)".format(h, s, l)
#用一張圖片作為詞雲的模板
maskcolud=np.array(Image.open(r"D:/baogao/0.jpg"))
#開啟要生成詞雲的文字檔案的位置
nedcloudpath=open("D:/baogao/職位福利.txt","rb").read()
#開啟之後用jieba切割
jiebapath=jieba.cut(nedcloudpath,cut_all=True)
#以空格為分割
jiebapathsplit=" ".join(jiebapath)
#設定詞雲對應屬性
produCloud=WordCloud(
width=300,
height=300,
background_color="white",
mask=maskcolud,
font_path='C:\windows\Fonts\STZHONGS.TTF',
max_words=200,
stopwords=STOPWORDS,
max_font_size=60,
random_state=50,
scale=0.5,
color_func=random_color_func
).generate(jiebapathsplit)
ImageColorGenerator(maskcolud)
#對詞雲進行顯示
produCloud.to_file('ciyu.jpg')
plt.imshow(produCloud)
plt.axis("off")
plt.show()
8.4資料分析崗位要求部分程式碼
#薪酬影響因素分析
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 讀取資料
df1 = pd.read_csv('D:/baogao/lagou_data2.csv', encoding = 'utf-8') #原來的gbk不能用!!!
c1=df1['城市'].count()
#1.計算學歷水平與工資關係,繪製柱狀圖
df2=df.groupby('學歷要求')['平均工資'].agg([np.mean]) #agg函式分組統計
count3=pd.Series(df2['mean'],df2.index) #將dataframe資料庫轉化為序列series
count3=count3.sort_values(ascending=False) #降序排列
plt.title("學歷水平與平均薪資")
plt.xlabel("學歷水平")
plt.ylabel("平均工資")
plt.bar(count3.keys(),count3)
plt.savefig('學歷與工資關係.jpg') #儲存為圖片
plt.show()
#2.計算工作經驗與平均工資關係
df3=df.groupby('工作經驗')['平均工資'].agg([np.mean])
count5=pd.Series(df3['mean'],df3.index) #將dataframe資料框轉化為序列series
count5=count5.sort_values(ascending=False)
plt.title("工作經驗與平均薪資")
plt.xlabel("工作經驗")
plt.ylabel("平均工資")
plt.bar(count5.keys(),count5)
plt.savefig('工作經驗與平均工資關係.jpg')
plt.show()
#3.計算不同融資階段的工資水平
df4=df.groupby('融資階段')['平均工資'].agg([np.mean])
count6=pd.Series(df4['mean'],df4.index) #將dataframe轉化為序列
count6=count6.sort_values(ascending=False)
plt.title("融資階段與平均薪資")
plt.xlabel("融資階段")
plt.ylabel("平均工資")
plt.bar(count6.keys(),count6)
plt.savefig('融資階段與工資關係.jpg')
plt.show()
#4.計算不同城市平均工資分佈狀況
df5=df.groupby('城市')['平均工資'].agg([np.mean])
count7=pd.Series(df5['mean'],df5.index) #將dataframe轉化為序列
count7=count7.sort_values(ascending=False)
count7=count7[0:15] #取排名前15位
plt.title("不同城市薪資")
plt.xlabel("城市")
plt.ylabel("平均工資")
plt.bar(count7.keys(),count7)
plt.savefig('不同城市與工資關係.jpg')
plt.show()
8.5拉勾網資料爬取部分程式碼
#拉勾網全國前100頁資料分析師招聘資料爬取
import requests
import math
import pandas as pd
import time
def get_json(url,num):
my_headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
'Host': 'www.lagou.com',
'Referer': 'https://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90?px=default&city=%E5%85%A8%E5%9B%BD',
'X-Anit-Forge-Code': '0',
'X-Anit-Forge-Token': 'None',
'X-Requested-With': 'XMLHttpRequest'
}
my_data = {
'first': 'true',
'pn':num,
'kd':'資料分析'}
res = requests.post(url, headers = my_headers, data = my_data)
res.raise_for_status()
res.encoding = 'utf-8'
# 得到包含職位資訊的字典
page = res.json()
return page
def get_page_num(count):
#計算要抓取的頁數
# 每頁15個職位,向上取整
res = math.ceil(count/15) #得到大於或等於該數值的最小整數
# 拉勾網最多顯示30頁結果
if res > 100:
return 100
else:
return res
def get_page_info(jobs_list):
'''''對一個網頁的職位資訊進行解析,返回列表'''
page_info_list = []
for i in jobs_list:
job_info = []
job_info.append(i['city'])
job_info.append(i['companyFullName'])
job_info.append(i['companyShortName'])
job_info.append(i['companySize'])
job_info.append(i['financeStage'])
job_info.append(i['district'])
job_info.append(i['positionName'])
job_info.append(i['workYear'])
job_info.append(i['education'])
job_info.append(i['salary'])
job_info.append(i['positionAdvantage'])
page_info_list.append(job_info)
return page_info_list
#返回特定資訊構建表格
def main():
url = 'https://www.lagou.com/jobs/positionAjax.json?px=default&needAddtionalResult=false'
# 先設定頁數為1,獲取總的職位數
page_1 = get_json(url,1)
total_count = page_1['content']['positionResult']['totalCount']
num = get_page_num(total_count)
total_info = []
time.sleep(40) #間隔40秒
print('職位總數:{},頁數:{}'.format(total_count,num))
for n in range(1,num+1):
# 對每個網頁讀取JSON, 獲取每頁資料
page = get_json(url,n)
jobs_list = page['content']['positionResult']['result']
page_info = get_page_info(jobs_list)
total_info += page_info
print('已經抓取第{}頁, 職位總數:{}'.format(n, len(total_info)))
# 每次抓取完成後,暫停一會,防止被伺服器拉黑
time.sleep(40)
#將總資料轉化為data frame再輸出
df = pd.DataFrame(data = total_info,columns = ['城市','公司全名','公司簡稱','公司規模','融資階段','區域','職位名稱','工作經驗','學歷要求','工資','職位福利'])
df.to_csv('lagou_jobs.csv',index = False)
print('已儲存為csv檔案.')
if __name__== "__main__":
main()