0 前言
作為一名數據分析小白,經過一輪融匯貫穿學習后,也迫不及待想做一份數據分析報告,于是選取了現階段最感興趣的數據分析相關崗位招聘信息進行一波數據分析。
1 理解問題
確定分析的目的和方向
因為目前正在轉型成為一名數據分析師的路上,希望找些項目練練手,熟悉數據分析的完整流程,但又想著一箭雙雕,項目輸出的結果能夠服務于己,因此最終選擇了對招聘數據做分析,并從中窺探該行業(yè)的冰山一角(看下把自己拎到市場上能賣多少錢)并挖掘有利于自身發(fā)展的關鍵信息(怎樣才能賣個好價格)。
2 理解數據
結合業(yè)務,對數據透徹理解
此次獲取的數據是在GitHub上看到的爬蟲項目:招聘網站爬蟲,沒做太多改動就應用上了,爬取的是「前程無憂」含“數據分析”關鍵詞近兩個月的招聘信息,地點選取了兩處:廣州、深圳,最后一共爬取了5.2W+條數據,廣深各占一半。
ps_1:這里為何沒有選取各發(fā)展水平的代表城市,只因純屬個人喜好,錢多離家近,事少不少就布吉島(是份帶有個人感情的數據分析報告)
ps_2:本來打算把大灣區(qū)也帶上,無奈發(fā)現除廣深外整個珠三角的招聘數據加起來與廣深都不是同一個量綱就放棄了
首先預覽下數據概況:
cv.info()
cv.head()
可以發(fā)現:
薪資、發(fā)布時間、職位信息有部分缺失值;
發(fā)布日期缺失年份信息,存在跨年時不便于排序;
薪資一列,格式不統一,而常見薪資單位為 千/月;
于是理解數據后進入下一環(huán)節(jié):數據清洗。
3 數據清洗
對數據進行預處理,包括缺失值、異常值和重復值的處理
重復值處理;考慮到同一條招聘可能會多次發(fā)布,因此去重時以 職位名稱+公司名稱 為唯一索引,進行去重處理,并保留最新記錄:
cv.drop_duplicates(['職位名稱','公司名稱'], keep='first', inplace=True)
缺失值處理:首先計算缺失率,發(fā)現薪資一列的缺失率為1.55%左右,占比較少;
cv.apply(lambda x: np.sum(x.isnull()) / len(x))['薪資']
故作刪除薪資缺失記錄處理:
cv.dropna(subset=['薪資'], how='any', inplace=True)
而對于職位信息、公司信息的缺失值,由于存在相應的薪資數據,不做刪除處理,而是用“暫無”填充;同時對職位信息做轉化為小寫處理,方便后續(xù)文本匹配。
cv['職位信息'] = cv['職位信息'].fillna('暫無').str.lower()cv['公司信息'] = cv['職位信息'].fillna('暫無')
異常值處理:重點關注薪資一列,先來看下目前的格式統計情況:
cv['薪資'].str[-3:].value_counts(normalize = True)
考慮到招聘信息中可能包含部分實習崗位,不在本次分析范圍內,故做刪除處理(考慮到刪除操作的重復調用,故定義了刪除函數drops(col, tag);
def drops(col, tag):? cv.drop(cv[cv[col].str.contains(tag)].index, inplace=True)
drops('職位名稱', '實習')
由于主流的工資標簽格式都是前三類,因此刪除其余格式的記錄:
drops('薪資', '元/天'); drops('薪資', '/小時'); drops('薪資', '下/月'); drops('薪資', '上/月'); drops('薪資', '下/年'); drops('薪資', '上/年');
薪資列的類型是文本,不方便做統計分析,因此進行文本處理,分離出薪資下限、薪資上限、薪資標簽,計算薪資均值,并統一以 千/月 為基準單位:
# 添加薪資標簽,區(qū)分年薪和月薪,薪資單位千和萬# ['萬/月':0, '萬/年':1, '千/月':2]
cv['salary_tag'] = np.where(cv['薪資'].str.contains('年'), 1, np.where(cv['薪資'].str.contains('千'),2 ,0))
cv['divisor'] =? np.where(cv['薪資'].str.contains('年'), 12, np.where(cv['薪資'].str.contains('千'),10 ,1))
cv['salary_min'] = (cv['薪資'].apply(lambda x: str(x).split('-')[0]).astype('float') / cv['divisor'] * 10).astype('int')
cv['salary_max'] = (cv['薪資'].apply(lambda x: str(x).split('-')[1][:-3]).astype('float') / cv['divisor'] * 10).astype('int')
cv['salary_unit'] = cv['薪資'].apply(lambda x: str(x).split('-')[1][-3:])cv['salary_avg'] = (cv['salary_min'] + cv['salary_max']) / 2
通過觀察升序后的薪資尾部數據,發(fā)現有部分異常大的離群值(個數均為1),因此刪除部分離群值,便于后續(xù)分析統計與展示;
# 刪掉部分離群值,薪資下限高于30k的,占比為0.59%
print(cv['salary_min'].value_counts().tail(10))
#print((round((cv[cv['salary_min'] > 30]['salary_min'].count() / cv.shape[0] * 100), 2)).astype('str') + '%' ) #Out: 0.59%
cv.drop(cv[cv['salary_min'] > 30].index, inplace=True)
至此,數據預處理暫告一段落。
數據分析和可視化
按照相關方法,對數據進行分析并通過可視化展示結果
考慮到招聘單位往往按薪資區(qū)間的下限開工資,因此后續(xù)分析薪資時主要以薪資下限(對應列 cv['salary_min'] )做分析;
通過按城市分類展示箱圖發(fā)現,深圳的薪資表現整體都要優(yōu)于廣州;雖下四分位數持平,但其余指標深圳的表現均超過廣州,說明數據分析相關的起步工作兩地薪資持平,但發(fā)展空間和天花板實屬深圳占優(yōu)。
以薪資下限與上限為坐標,以城市為分類變量繪制散點圖,觀察薪資定位情況;可以發(fā)現,同樣的薪資下限,深圳在薪資上限的表現會更加突出
從散點圖也可以看出,薪資區(qū)間定位較為散亂,因此考慮對薪資利用cut()進行月薪重分類,分區(qū)方式參考“前程無憂”的過濾條件(此處區(qū)間為左閉右開,如 8-10 為 8k ≤ x<10k)
cv.salary_min.sort_values()
bins = [0, 2, 3, 4.5, 6, 8, 10, 15, 20, 30]
level = ['0-2','2-3','3-4.5','4.5-6','6-8','8-10','10-15','15-20','20-30']
cv['level'] = pd.cut(cv['salary_min'], bins = bins, labels=level, right=False) #right=False表示左閉右開
cv_level = cv['level'].value_counts()
對重采樣后的薪資區(qū)間進行分類統計,可以發(fā)現,整體薪資分布符合721原則,即TOP 20%,中間70%,末尾10%;6-8k的月薪分布最多,占據了四分之一。
若將城市分類加入區(qū)間分布圖,繪制疊加柱狀圖,結論大體如箱圖所示
做完了薪資整體分布的概覽以及按城市分類對比后,發(fā)現“數據分析”崗位并沒有想象中高薪,8k以下的月薪占比超過半數(55.43%),不過萬的月薪占比更是接近四分之三(73.92%),那么究竟“月薪過萬的數據分析師”是否唬人呢?
print('%.2f%%' %((cv[cv['salary_min'] < 8].count() / cv.shape[0])['salary_min'] * 100))
print('%.2f%%' %((cv[cv['salary_min'] < 10].count() / cv.shape[0])['salary_min'] * 100))
cv['salary_min'].describe()
挑選發(fā)布“數據分析”相關的職位名稱用詞頻率前20名進行觀察,發(fā)現大多數崗位都不符合“數據分析師”的頭銜,但回到開頭數據源的獲取階段,抓取的是含“數據分析”關鍵詞的職位,而“數據分析”這個概念本身就非常寬泛,因為在實際工作中和數據打交道是司空見慣的事情,難易不同,主輔不同,工作性質不同,都會使得“數據分析”這項技能的實際應用有所不同。
cv.groupby(by=['職位名稱'])['職位名稱'].count().sort_values(ascending=False).head(20)
因此考慮對職位名稱的判斷,添加分類變量列,來區(qū)分不同種類的工作:
數據挖掘、算法工程師為一類,理解為偏技術數據分析類崗位(下簡稱挖掘崗);
數據分析、BI、數據運營為一類,理解為偏業(yè)務數據分析類崗位(下簡稱分析崗);
其余的判斷為非數據分析類崗位(下簡稱其他崗)
# 對職位進行重分類:數據挖掘|算法 == 2, 數據分析|數據運營|BI == 1, 其余 == 0
is_skill = re.compile(r'數據挖掘|算法')is_analyst = re.compile(r'數據分析|數據運營|BI')
cv['job_type'] = np.where(cv['職位名稱'].apply( lambda x: is_skill.search(x) != None ), 2,
????????np.where(cv['職位名稱'].apply( lambda x: is_analyst.search(x) != None ), 1, 0))
經過重新分類后,value_counts()的結果為:挖掘崗有174條、分析崗有1245條、其他崗為40443條;結合箱圖分析,挖掘崗的整體表現遠超過其余兩類崗位,而分析崗相較于其他崗的起步更高,不過從高薪層面看則差距不大;
箱圖,按職位類別分類
通過pandas的describe()也能反映不同職位類別的對比情況;回到剛提出的問題,數據分析工作是否穩(wěn)妥月薪過萬呢?從中位數的情況來看(此處不分析平均值,是因為預處理時刪除了部分月薪過高的離群值,平均值可能偏低,但對中位數影響較?。?,并不樂觀,分析崗的中位數僅為8k;
def salary_type_desc(col):? ?
????type = cv.groupby('job_type')[col].describe()? ?
????all = pd.DataFrame(cv[col].describe()).T
????all.index = ['all']? ?
????return pd.concat([type, all])# 按職位分類的月薪統計信息(薪資下限)
salary_type_desc('salary_min')
按職位分類的月薪統計信息(薪資下限)
于是掏出了沉箱底已久的薪資均值、薪資上限,發(fā)現月入過萬這個指標藏在了分析師的「薪資均值」中位數,以及“數據分析”相關崗位「薪資上限」中位數里。
按職位分類的月薪統計信息(薪資均值)
按職位分類的月薪統計信息(薪資上限)
既然已經知道高薪往哪找,那么就來看看如何往心儀的崗位靠攏。首先嘗試統計出常見技能的出現頻次并繪制柱狀圖,可以發(fā)現排名前十的分別是:EXCEL、PPT、SQL、Python、MySQL、Hadoop、Oracle、SPSS、Spark、HIVE;
#關鍵詞搜索函數封裝,傳入關鍵詞列表,輸出計數列表def key_list_search(key):? ? cnt = []? ? for i in range(0, len(key)):? ? ? ? cnt.append(cv[cv['職位信息'].str.contains(key[i])]['職位信息'].count())? ? return cnt
那么技能要求究竟和薪資是否掛鉤呢?不妨來對技能與薪資的相關性進行評估,此處挑選了四大技能EXCEL、SQL、Python、Hadoop作為二分類變量,通過相關系數來評估相關性。
#定義匹配函數,挑選四個主流技能觀察相關性
def is_match(col, key):? ?
????return cv[col].str.contains(key)
cv['is_sql'] =np.where(is_match('職位信息', 'sql'), 1, 0)
cv['is_python'] =np.where(is_match('職位信息', 'python'), 1, 0)
cv['is_hadoop'] =np.where(is_match('職位信息', 'hadoop'), 1, 0)
cv['is_excel'] =np.where(is_match('職位信息', 'excel'), 1, 0)
cv[['is_excel', 'is_sql', 'is_python', 'is_hadoop', 'salary_min']].corr(method = 'spearman')
結果顯示,四大技能均呈若弱相關,其中正相關性強弱排名為 Python ≥ SQL > Hadoop,而EXCEL呈現負相關;另外,值得注意的是 SQL 和 Python 通常在招聘要求上經常成對出現(其相關系數高達0.5)
四大技能相關系數矩陣
同樣地,也將相關系數矩陣可視化(此處利用的是pandas_profiling)
結論和建議
根據結果得出結論并提出有價值的建議
Q1:數據分析師真的月入過萬嗎?
A1:既假亦真。假就假在以偏概全,準確來說,應是數據分析師的「薪資均值」中位數過萬,也可以說“數據分析”相關崗位「薪資上限」中位數過萬;但按照實際市場供求,數據分析師的「薪資下限」中位數并未過萬。
Q2:廣深兩地哪家好?
A2:剛起步不糾結,有好機會就上,想要做大做強還是在深圳為妙。
Q3:(偏業(yè)務)數據分析師必備技能?
A3:
EXCEL\PPT\SQL\Python是四大天王;
而且對SQL有要求的企業(yè),通常也要求會Python;
技能與薪資不具備強相關性,但技能永遠只是輔助,數據敏感和熟悉業(yè)務才是王牌。