第八課:案例分析 - 泰坦尼克數據
本節課將重點分析泰坦尼克號沉船事故,我們將探索是什么因素決定了最后是否生還。
我們將將前面課程所學過的知識點融會貫通,舉一反三
新增知識點:
? ? ? ?缺失值處理:pandas中的fillna()方法
? ? ? ?數據透視表:pandas中的pivot_table函數
我們上一篇文章用以前的知識將泰坦尼克案例的前面數據簡單操作了一番,剩下的內容會有新的知識點,不知道一篇文章裝不裝得下,來了啊!正文:
2、缺失值處理
真實數據往往某些變量會有缺失值。
首先,我們用 info( ) 語句操作,看到整份數據的大概情況:
從這份數據我們可以發現,這里一共有 891 行數據,所以在中間那一列數據中看到的不是 891 個數據的,都是有缺失值的。比如年齡Age這一列,有714個非空數值,就有 891-714=177 個缺失值。又比如船艙號碼 cabin,缺失值就更多了。登船碼頭的缺失值比較少,后面可以不用處理。
這些缺失值是怎么處理的呢?一般是三種處理方法:不處理/丟棄/填充。
這里,cabin有超過70%以上的缺失值,我們可以考慮直接丟掉這個變量。 -- 刪除某一列數據
像Age這樣的重要變量,有20%左右的缺失值,我們可以考慮用中位值來填補。-- 填補缺失值
我們一般不提倡去掉帶有缺失值的行,因為其他非缺失的變量可能提供有用的信息。-- 刪除帶缺失值的行
刪除帶缺失值的行(一般不建議):df.dropna( )
刪除某一列:df.drop('column_name', axis=1, inplace=True)
填充缺失值:df.column_name.fillna( )
axis=1,代表刪除的是一列的數據,也就是 column_name 這一列。inplace=True,表示在 df 這個原始數據上面進行修改。
其實我們這節課重點的是最后一個:填充缺失值。fill 是填充,na 是缺失值的代稱。
我們在 info( ) 這個運行中可以看到 Age 的缺失值不少,下面將使用中位數來填充 缺失值。
填補年齡數據中的缺失值
直接使用所有人年齡的中位數來填補
為了方便后面的比較,我們首先用 describe 統計數據。
這份數據照樣是可以看到,非缺失值 count 是有 714,平均值 mean 是 29.6歲,標準差 std 是 14.5,這時可以注意一下 50% ?那個數據:28。
為了防止數據有改動,我們在開始之前需要重新載入數據。
正確的中位數可以使用 median 的方法獲取,得到的數和上面的 50% 的數是一樣的。
把中位數賦值給 age_median1,這個操作體現在第二行代碼。我的理解是,要是這里不重新賦值的話,后面需要用到這個中位數的時候,就需要完整碼出 titanic_df.Age.median( ) 這一句,重新賦值就可以直接使用 age_median1 來代替稍微長一點的句子了。
titanic_df.Age.fillna(age_median1,inplace=True) 中,因為使用到Age這列數據,然后用 fillna 來實現填充,所以語句用 titanic_df.Age.fillna( ) 來表達,括號里面需要填的參數就是需要填充的值,也就是里面的缺失值都是由剛剛賦值的 age_median1 來代替。逗號后面再加上inplace=True,表示在原來的 df 數據中進行修改了,如果不加上這個參數,就需要把填充后的值重新賦值給 Age 這一列,所以 inplace 這個動作是為了簡單起見。
再來看我們得到的結果,這個時候的非空缺失值已經變成了891,平均值也從原本的29.7降到了29.4,因為我們剛剛填充的中位數是28,比原來的平均值小,所以會有所新的平均值也會有所下降。
上面講的是所有人的年齡中位數,現在我們進一步來思考:性別因素,會怎么影響結果呢?
考慮性別因素,分別用男女乘客各自年齡的中位數來填補
由于上面的操作已經對原始數據進行修改了,所以要是我們需要重新分類,那就要重新載入原始數據,不然后面的操作都會以上一步填充了所有年齡缺失值的基礎上操作的哦!這個虧我吃過。。。
我們得到的女性中位數是 27,男性的是 29,還是有差距的吧!我們后面需要用到的是,用得出的中位數來填充男女的缺失值。
接下來的步驟,按照以前,通常的思路是用布爾型索引取到女性中缺失值的數據,然后用 27 重新賦值;同理可求男性的操作。
但是我們這節課學了fillna 這個新的方法啊!
不過剛剛我們使用 fillna 的時候,填充的只是一個數值,這里不止一個數值,就需要根據不同的情況來填充。此時可以用到 Pandas 中里的一個小技巧,Pandas 的值在運算的過程中,會根據索引的值來進行自動的匹配。在這里我們可以看到這里的索引是 female 和 male 兩個值,如果原始數據也可以用性別來進行索引的話,就可以用 fillna 自動匹配相應的索引形式進行填充了。
所以這里要對原來的數值重新設置索引,一開始是 0 1 2 這樣的數值,現在要把它設置成性別這一列數據。用 set_index 語句,用 Sex 來進行索引,同時加入參數 inplace=True,表示在原來的數據上進行修改。
inplace=True的含義應該講了第三遍了,其實我覺得要是不是很明白這個語句的用法時,你可以先不加上這一句,跟著打代碼,然后到后面運行的哪一步你發現和老師的代碼不一樣的時候,你就知道這個語句的重要性了。
我們可以看到這里的運行結果 列索引變成了 Sex,列首索引是 male 和 female ,在行首 Sex 已經不存在了。
我們將這里分類中位數賦值為 age_median2。填充的套路和上面也是一樣一樣的,根據 Pandas 的自動匹配,填充的時候會根據索引來匹配不同的值了。因為后續需要用到 Sex 這一列,所以這里也需要重置索引,將索引變成它的列。這里使用 reset_index。
非空值是 891 時就說明缺失值全部填充完畢了,這時候的均值是29.4。
所以到這里,我們把性別分類的缺失值也用各自的中位數填充完畢了。下一步要考慮的是,同時兩個因素的影響:
同時考慮性別和艙位因素
那我們首先來看一下,在不同年齡和不同艙位的中位數,有什么變化呢?
groupby 分組的對象分別是 Pclass 艙位 和 Sex 性別,由于這里需要考量的有兩個因素:性別和艙位,所以這里需要使用到中括號,后面加上用 Age.median 就可以得到分組的中位數了。
這里就有兩個索引,分別是艙位和性別,我們可以看到,隨著艙位的下降,它的年齡也是在下降的。用我們的話理解就是,年輕人普遍比年長的窮啊,年齡大一點的人積累的財富也多一點。
那接下來我們就用得出的中位數來各自重新賦值給艙位和性別。這時還是可以用 fillna 的,但是需要設置二重索引。
套路還是一樣的,把這里得出的中位數賦值為 age_median3,然后對索引進行重新的賦值,同樣的,這里有兩個因素,也是使用中括號,用 set_index 的方法。
然后來看一下重置索引后的數據。看輸出我們是可以看到二重索引的,第一列的組合內容一共有 3*2=6 種情況。在列上面,已經沒有 Pclass 和 Sex 兩列數據了,因為此刻它們已經在索引上了。
現在按同樣的方法 fillna ,用索引值來匹配不同的中位數。
額。。。這兩張看起來和上面的一毛一樣啊,是我哪里錯了嗎。。。?
為了還原這樣的索引,這里用 reset來重置
這里的輸出可以看到非空數值已經是891了,表示已經填滿缺失值了。平均值下降到了29.1歲,因為三等艙的人數比較多,而且年齡比較小,所以拉低了平均值。
我們總結一下,這里使用的 fillna 的方法,可以對總體的中位數進行操作,或者分類之后對中位數進行操作。分組之后由于有索引,所以同時也需要對原始數據進行索引,對于相同索引值,可以用匹配來進行填充。
在課堂答疑的時候,有同學問為什么要用中位數來填充缺失值呢?
老師回答其實也是可以用平均值來填充的,這里的中位數和平均值相差不大,極端值不明顯。中位數在老師看來比較能夠表示人群的屬性,老師舉了我國的人均收入這個例子,是用均值還是中位數比較好呢?要是用均值的話,大家都在拖后腿了。。。
然后有同學問,設置索引有什么作用?
老師回答:設置索引有匹配的作用,在剛剛男性和女性的分類中,就可以通過男性的屬性來匹配男性的中位數,女性的來匹配女性的中位數。通過第一個例子可以看到fillna 要是沒有索引的話,會給所有的數值都填充相同的一個值。
后面還有一大半內容。。。老師說了這節課是一個加量的全家桶,明天繼續更新后面的吧。。。