1. 程式人生 > >用pandas進行資料分析實戰

用pandas進行資料分析實戰

主要內容是進行資料讀取,資料概述,資料清洗和整理,分析和視覺化。按照本教程,相信大家的Pandas會上到一個新臺階,遇到文中沒有提及的錯誤,通過搜尋引擎解決吧。

首先載入我們的練習資料。

在pandas中,常用的載入函式是read_csv。除此之外還有read_excel和read_table,table可以讀取txt。若是伺服器相關的部署,則還會用到read_sql,直接訪問資料庫,但它必須配合mysql相關包。

read_csv擁有諸多的引數,encoding是最常用的引數之一,它用來讀取csv格式的編碼。這裡使用了gb2312,該編碼常見於windows,如果報錯,可以嘗試utf-8。

sep引數是分割符,有些csv檔案用逗號分割列,有些是分號,有些是\t,這些都需要具體設定。header引數為是否使用表頭作為列名。

names引數可以為列設定額外的名字,比如csv中的表頭是中文,但是在pandas中最好轉換成英文。

上述是主要的引數,其他引數有興趣可以學習。一般來說,csv的資料都是乾淨的,excel檔案則有合併單元格這種噁心的玩意,儘量避免。

這裡寫圖片描述

現在有了資料df,首先對資料進行快速的瀏覽。

這裡寫圖片描述

這裡列舉出了資料集擁有的各類欄位,一共有6876個,其中companyLabelList,businessZones,secondType,positionLables都存在為空的情況。
公司id和職位id為數字,其他都是字串。
因為資料集的資料比較多,如果我們只想瀏覽部分的話,可以使用head函式,顯示頭部的資料,預設5,也可以自由設定引數,如果是尾部資料則是tail。

這裡寫圖片描述

資料集中,最主要的髒資料是薪資這塊,後續我們要拆成單獨的兩列。

看一下是否有重複的資料。

這裡寫圖片描述

unique函式可以返回唯一值,資料集中positionId是職位ID,值唯一。配合len函式計算出唯一值共有5031個,說明有多出來的重複值。

使用drop_duplicates清洗掉。

這裡寫圖片描述

drop_duplicates函式通過subset引數選擇以哪個列為去重基準。keep引數則是保留方式,first是保留第一個,刪除後餘重複值,last還是刪除前面,保留最後一個。
duplicated函式功能類似,但它返回的是布林值。
接下來加工salary薪資欄位。目的是計算出薪資下限以及薪資上限。

這裡寫圖片描述

薪資內容沒有特殊的規律,既有小寫k,也有大小K,還有「k以上」這種蛋疼的用法,k以上只能上下限預設相同。

這裡需要用到pandas中的apply。它可以針對DataFrame中的一行或者一行資料進行操作,允許使用自定義函式。

這裡寫圖片描述

我們定義了個cut_word函式,它查詢「-」符號所在的位置,並且擷取薪資範圍開頭至K之間的數字,也就是我們想要的薪資上限。

apply將cut_word函式應用在salary列的所有行。

「k以上」這類髒資料怎麼辦呢?find函式會返回-1,如果按照原來的方式擷取,是word[:-2],不是我們想要的結果,所以需要加一個if判斷。

因為python大小寫敏感,我們用upper函式將k都轉換為K,然後以K作為擷取。這裡不建議用「以上」,因為有部分髒資料不包含這兩字。

在word_cout函式增加了新的引數用以判斷返回bottom還是top。apply中,引數是新增在函式後面,而不是裡面的。這點需要注意。

這裡寫圖片描述

把topSalary和bottomSalary都改成int型別的。
接下來求解平均薪資。

這裡寫圖片描述

資料型別轉換為數字,這裡引入新的知識點,匿名函式lambda。很多時候我們並不需要複雜地使用def定義函式,而用lamdba作為一次性函式。

lambda x: * ,前面的lambda x:理解為輸入,後面的星號區域則是針對輸入的x進行運算。案例中,因為同時對top和bottom求平均值,所以需要加上x.bottomSalary和x.topSalary。word_cut的apply是針對Series,現在則是DataFrame。

axis是apply中的引數,axis=0表示將函式用在行,axis=1則是列。

這裡的lambda可以用(df_duplicates.bottomSalary + df_duplicates.topSalary)/2替代。

到此,資料清洗的部分完成。切選出我們想要的內容進行後續分析(大家可以選擇更多資料)。

這裡寫圖片描述

先對資料進行幾個描述統計。
value_counts是計數,統計所有非零元素的個數,以降序的方式輸出Series。資料中可以看到北京招募的資料分析師一騎絕塵。

我們可以依次分析資料分析師的學歷要求,工作年限要求等。

這裡寫圖片描述

針對資料分析師的薪資,我們用describe函式。

這裡寫圖片描述

它能快速生成各類統計指標。資料分析師的薪資的平均數是17k,中位數是15k,兩者相差不大,最大薪資在75k,應該是資料科學家或者資料分析總監檔位的水平。
標準差在8.99k,有一定的波動性,大部分分析師薪資在17+-9k之間。

一般分類資料用value_counts,數值資料用describe,這是最常用的兩個統計函式。

說了這麼多文字,還是不夠直觀,我們用圖表說話。

pandas自帶繪圖函式,它是以matplotlib包為基礎封裝,所以兩者能夠結合使用。

這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

首先載入字型管理包,設定一個載入中文字型的變數,不同系統的路徑不一樣。boxplot是我們呼叫的箱線圖函式,column選擇箱線圖的數值,by是選擇分類變數,figsize是尺寸。

ax.get_xticklabels獲取座標軸刻度,即無法正確顯示城市名的白框,利用set_fontpeoperties更改字型。於是獲得了我們想要的箱線圖。改變字型還有其他方法,
大家可以網上搜索關鍵字「matplotlib 中文字型」,都有相應教程。

從圖上我們看到,北京的資料分析師薪資高於其他城市,尤其是中位數。上海和深圳稍次,廣州甚至不如杭州。
現在來處理標籤資料。

這裡寫圖片描述

現在的目的是統計資料分析師的標籤。它只是看上去幹淨的資料,元素中的[]是無意義的,它是字串的一部分,和陣列沒有關係。

你可能會想到用replace這類函式。但是它並不能直接使用。df_clean.positionLables.replace會報錯,為什麼呢?因為df_clean.positionLables是Series,並不能直接套用replace。apply是一個好方法,但是比較麻煩。

這裡需要str方法。

這裡寫圖片描述

dropna()將所有含有NaN項的行刪除,dropna()經常用來清理無效資料。
str方法允許我們針對列中的元素,進行字串相關的處理,這裡的[1:-1]不再是DataFrame和Series的切片,而是對字串擷取,這裡把[]都擷取掉了。
如果漏了str,就變成選取Series第二行至最後一行的資料,切記。
使用完str後,它返回的仍舊是Series,當我們想要再次用replace去除空格。還是需要新增str的。現在的資料已經乾淨不少。

positionLables本身有空值,所以要刪除,不然容易報錯。再次用str.split方法,把元素中的標籤按「,」拆分成列表。

這裡是重點,通過apply和value_counts函式統計標籤數。因為各行元素已經轉換成了列表,所以value_counts會逐行計算列表中的標籤,apply的靈活性就在於此,它將value_counts應用在行上,最後將結果組成一張新表。

這裡的運算速度會有點慢,別擔心。

這裡寫圖片描述

用unstack完成行列轉換,看上去有點怪,因為它是統計所有標籤在各個職位的出現次數,絕大多數肯定是NaN。

這裡寫圖片描述

將空值刪除,並且重置為DataFrame,此時level_0為標籤名,level_1為df_index的索引,也可以認為它對應著一個職位,0是該標籤在職位中出現的次數,之前我沒有命名,所以才會顯示0。部分職位的標籤可能出現多次,這裡忽略它。reset_index可以還原索引,重新變為預設的整型索引。

這裡寫圖片描述

最後用groupby計算出標籤出現的次數。到這裡,已經計算出我們想要的結果。除了這種方法,也可以使用for迴圈,大家可以試著練習一下,效率會慢不少。
這種寫法的缺點是佔用記憶體較大,拿空間換時間,具體取捨看大家了。

這裡寫圖片描述

載入wordcloud,anaconda沒有,自行下載吧。清洗掉引號,設定詞雲相關的引數。因為我是在jupyter中顯示圖片,所以需要額外的配置figsize,不然wide和height的配置無效。wordcloud也相容pandas,所以直接將結果傳入,然後顯示圖片,去除座標。大功告成。

這裡寫圖片描述