小白學 Python 數據分析(10):Pandas (九)數據運算
- 2020 年 3 月 3 日
- 筆記
人生苦短,我用 Python
前文傳送門:
小白學 Python 數據分析(2):Pandas (一)概述
小白學 Python 數據分析(3):Pandas (二)數據結構 Series
小白學 Python 數據分析(4):Pandas (三)數據結構 DataFrame
小白學 Python 數據分析(5):Pandas (四)基礎操作(1)查看數據
小白學 Python 數據分析(6):Pandas (五)基礎操作(2)數據選擇
小白學 Python 數據分析(7):Pandas (六)數據導入
小白學 Python 數據分析(8):Pandas (七)數據預處理
小白學 Python 數據分析(9):Pandas (八)數據預處理(2)
引言
前面我們介紹了很多關於 Pandas 的基礎操作以及拿到一份數據後首先要做的是對數據的基礎預處理。
本篇我們接著介紹當我們處理完數據後,可以對數據進行的一些計算操作。
本篇文章使用的數據為泰坦尼克的數據集,具體的數據集已經上傳至程式碼倉庫,有需要的同學可以自行取用。
數據來源是著名的 Kaggle :https://www.kaggle.com/ 。
中國的網路訪問有些慢,建議自己想辦法,實在不行,可以加小編微信,小編有個神奇的軟體,特別好用。
在正文內容開始前,小編先把數據中的表名的中英文對照列出來:
- PassengerId : 乘客ID
- Survived : 是否倖存
- Pclass : 乘客等級(1/2/3等艙位)
- Name : 姓名
- Sex : 性別
- Age : 年齡
- SibSp : 堂兄弟/妹個數
- Parch : 父母與小孩個數
- Ticket : 船票資訊
- Fare : 票價
- Cabin : 客艙
- Embarked : 登船港口
預處理
首先,我們拿到數據的第一步是先檢查一下數據品質,通過方法 info()
看下有數據品質:
import pandas as pd # 數據導入 data_train = pd.read_csv("train.csv") # 數據查看 print(data_train.info()) # 輸出內容 <class 'pandas.core.frame.DataFrame'> RangeIndex: 891 entries, 0 to 890 Data columns (total 12 columns): PassengerId 891 non-null int64 Survived 891 non-null int64 Pclass 891 non-null int64 Name 891 non-null object Sex 891 non-null object Age 714 non-null float64 SibSp 891 non-null int64 Parch 891 non-null int64 Ticket 891 non-null object Fare 891 non-null float64 Cabin 204 non-null object Embarked 889 non-null object dtypes: float64(2), int64(5), object(5) memory usage: 83.7+ KB None
上面這些數據到底說了個啥?
看過我前面文章的同學應該知道,info()
這個方法經常用作查看數據空值,很不辛,這裡有些屬性的數據不全,如:
- Age(年齡)屬性只有714名乘客有記錄
- Cabin(客艙)更是只有204名乘客是已知的
這裡我們進一步使用 describe()
看下這批數據的統計分析數據:
print(data_train.describe()) # 輸出內容 PassengerId Survived Pclass Age SibSp count 891.000000 891.000000 891.000000 714.000000 891.000000 mean 446.000000 0.383838 2.308642 29.699118 0.523008 std 257.353842 0.486592 0.836071 14.526497 1.102743 min 1.000000 0.000000 1.000000 0.420000 0.000000 25% 223.500000 0.000000 2.000000 20.125000 0.000000 50% 446.000000 0.000000 3.000000 28.000000 0.000000 75% 668.500000 1.000000 3.000000 38.000000 1.000000 max 891.000000 1.000000 3.000000 80.000000 8.000000 Parch Fare count 891.000000 891.000000 mean 0.381594 32.204208 std 0.806057 49.693429 min 0.000000 0.000000 25% 0.000000 7.910400 50% 0.000000 14.454200 75% 0.000000 31.000000 max 6.000000 512.329200
能看出來啥呢?
如果把目光聚焦在 mean
這一行上,可以看到大概 0.383838 的人最後獲救了,在 2 / 3 等倉的人要比 1 等倉的多得多(這不是廢話),平均年齡大概是 29.699118 (這個值計算的時候會忽略掉空值)等等。
算數運算
emmmmmmmmmm,寫到這裡小編髮現個問題,用這份數據演示算數運算屬實有點不大合適,滿臉尷尬。
小編這麼懶的人都寫到這了,肯定是不會換數據集了,各位看官就這麼湊合著看吧,先聲明一下,以下演示均無實際意義。
這一小節的標題是算數運算,那無非是加減乘除嘛,首先來看下兩列相加的示例,這裡是把堂兄弟姐妹和父母小孩加在一起,結果稍微有點意義,這個乘客的所有親屬:
print(data_train['SibSp'] + data_train['Parch']) # 輸出內容 0 1 1 1 2 0 3 1 4 0 .. 886 0 887 0 888 3 889 0 890 0 Length: 891, dtype: int64
兩列相減,這裡我們使用這個乘客的所有親屬再加上他本身減去存活人數,示例如下:
print(data_train['SibSp'] + data_train['Parch'] + 1 - data_train['Survived']) # 輸出內容 0 2 1 1 2 0 3 1 4 1 .. 886 1 887 0 888 4 889 0 890 1 Length: 891, dtype: int64
乘除同理,小編這裡就不演示,各位同學可以自己動手試試。
比較
這裡我們選用存活數和親屬數量做比較,幾個簡單的示例:
print(data_train['Survived'] > (data_train['SibSp'] + data_train['Parch'])) # 輸出內容 0 False 1 False 2 True 3 False 4 False ... 886 False 887 True 888 False 889 True 890 False Length: 891, dtype: bool
同理,這裡除了可以使用 >
還可以使用 >=
、 !=
、 <
和 <=
等運算符。
統計分析
前面我們使用 describe()
這個方法自動的獲取過當前數據集的一些統計數據,那麼我們如何手動的來獲取它呢?
統計非空值
首先是 count()
統計非空值:
# 按列統計 print(data_train.count()) # 輸出內容 PassengerId 891 Survived 891 Pclass 891 Name 891 Sex 891 Age 714 SibSp 891 Parch 891 Ticket 891 Fare 891 Cabin 204 Embarked 889 dtype: int64 # 按行統計 print(data_train.count(axis=1)) # 輸出內容 0 11 1 12 2 11 3 12 4 11 .. 886 11 887 12 888 10 889 12 890 11 Length: 891, dtype: int64 # 某一列單獨統計 print(data_train['Age'].count()) # 輸出內容 714
求和
接下來是求和, sum
這個函數想必各位都在 Excel 中用過,那麼在 Pandas 中是如何使用的,請看下面的示例:
# 按列求和 print(data_train.sum()) # 輸出內容 PassengerId 397386 Survived 342 Pclass 2057 Name Braund, Mr. Owen HarrisCumings, Mrs. John Brad... Sex malefemalefemalefemalemalemalemalemalefemalefe... Age 21205.2 SibSp 466 Parch 340 Ticket A/5 21171PC 17599STON/O2. 31012821138033734503... Fare 28693.9 dtype: object # 按行求和 print(data_train.sum(axis=1)) # 輸出內容 0 34.2500 1 114.2833 2 40.9250 3 95.1000 4 51.0500 ... 886 929.0000 887 939.0000 888 918.4500 889 948.0000 890 933.7500 Length: 891, dtype: float64
可以看到,在進行按列求和的時候, Pandas 把非數值類型的列直接將所有的欄位拼合在了一起,其實無太大意義。
求算數平均值
接下來是求算數平均值,這個函數是 mean()
,算數平均值有一個特點是極易受到極大極小值的影響,就比如我和小馬哥的資產平均超過了 100 億,這個其實和我基本上沒有半毛錢關係。
print(data_train.mean()) # 輸出內容 PassengerId 446.000000 Survived 0.383838 Pclass 2.308642 Age 29.699118 SibSp 0.523008 Parch 0.381594 Fare 32.204208 dtype: float64
mean()
實際是上對每一列進行了求平均值的運算,實際上可以通過 axis
參數按行獲取平均值,不過在當前的數據集毫無意義,小編這裡就不演示了。
求最大最小值
接下來是求最大最小值,在 Excel 其實可以直接通過排序來直觀的看到某一列的最大最小值,那麼,一起看一下在 Pandas 是如何獲取這兩個值:
print(data_train.max()) print('------------------------') print(data_train.min()) # 輸出內容 PassengerId 891 Survived 1 Pclass 3 Name van Melkebeke, Mr. Philemon Sex male Age 80 SibSp 8 Parch 6 Ticket WE/P 5735 Fare 512.329 dtype: object -------------------------------------------- PassengerId 1 Survived 0 Pclass 1 Name Abbing, Mr. Anthony Sex female Age 0.42 SibSp 0 Parch 0 Ticket 110152 Fare 0 dtype: object
可以看到,在 Pandas 中獲取最大最小值是使用了兩個函數, max()
和 min()
,通過字面意思大家也懂,這裡同樣要提一下是默認是按照列來獲取最大最小值,如果有需要,也可以通過參數 axis
來按照行來獲取。
中位數
相比較前面提到過的算數平均數,中位數是一個非常不錯的反應一組數據的一般情況的一個數據,不易受到極大值和極小值的影響。
在 Pandas 中,獲取中位數是使用 median()
函數:
print(data_train.median()) # 輸出內容 PassengerId 446.0000 Survived 0.0000 Pclass 3.0000 Age 28.0000 SibSp 0.0000 Parch 0.0000 Fare 14.4542 dtype: float64
同樣, median()
函數也可以通過 axis
參數來按照行進行獲取。
眾數
眾數就是出現次數最多的那個數,這裡我們使用到的函數是 mode()
:
print(data_train.mode()) # 輸出內容 Survived Pclass Sex Age SibSp Parch Fare Embarked 0 0 3 male 24.0 0 0 8.05 S [891 rows x 12 columns] # 單獨獲取某列眾數 print(data_train['Sex'].mode()) # 輸出內容 0 male dtype: object
方差標準差
方差和標準差其實都是用來表示數據的離散程度,標準差是方差的平方根。
在 Pandas 中,計算方差是使用 var()
函數,而計算標準差是使用 std()
函數:
print(data_train.var()) # 輸出內容 PassengerId 66231.000000 Survived 0.236772 Pclass 0.699015 Age 211.019125 SibSp 1.216043 Parch 0.649728 Fare 2469.436846 dtype: float64 print(data_train.std()) # 輸出內容 PassengerId 257.353842 Survived 0.486592 Pclass 0.836071 Age 14.526497 SibSp 1.102743 Parch 0.806057 Fare 49.693429 dtype: float64
各位閑著沒事兒的同學可以核實一下把標準差平方一下看看是不是方差。
反正小編怕翻車,是專門核實了一下,確實沒有問題,如果哪位同學核實出來有問題,可能是小編這台電腦有問題。
求分位數
分位數是一種比中位數更加詳細的根據位置的指標,在統計學中,最常用的是四分位數:
- 第一四分位數(Q1),又稱「較小四分位數」,等於該樣本中所有數值由小到大排列後第 25% 的數字;
- 第二四分位數(Q2),又稱「中位數」,等於該樣本中所有數值由小到大排列後第 50% 的數字;
- 第三四分位數(Q3),又稱「較大四分位數」,等於該樣本中所有數值由小到大排列後第 75% 的數字。
在 Pandas 中,獲取分位數是使用 quantile()
函數,但是在使用的過程中,一定要標識清楚去的分位數值:
print(data_train.quantile(0.25)) print('-----------------------------------------') print(data_train.quantile(0.5)) # 輸出內容 PassengerId 223.5000 Survived 0.0000 Pclass 2.0000 Age 20.1250 SibSp 0.0000 Parch 0.0000 Fare 7.9104 Name: 0.25, dtype: float64 ----------------------------------------- PassengerId 446.0000 Survived 0.0000 Pclass 3.0000 Age 28.0000 SibSp 0.0000 Parch 0.0000 Fare 14.4542 Name: 0.5, dtype: float64
這裡的驗證可以對比我們前面取出來的中位數,看下是否一致就好,如果不一致,可能需要換電腦了。
相關性
相關性運算是指兩個事務之間的關聯程度,這裡我們可以使用 corr()
函數來進行相關性運算。
使用方式:
DataFrame.corr(method=’pearson’, min_periods=1)
參數說明:
method:可選值為 {‘pearson’, ‘kendall’, ‘spearman’}
- pearson:Pearson相關係數來衡量兩個數據集合是否在一條線上面,即針對線性數據的相關係數計算,針對非線性數據便會有誤差。
- kendall:用於反映分類變數相關性的指標,即針對無序序列的相關係數,非正太分布的數據
- spearman:非線性的,非正太分析的數據的相關係數
我們一般比較常用的是皮爾遜相關係數:
print(data_train.corr(method='pearson')) # 輸出內容 PassengerId Survived Pclass Age SibSp Parch PassengerId 1.000000 -0.005007 -0.035144 0.036847 -0.057527 -0.001652 Survived -0.005007 1.000000 -0.338481 -0.077221 -0.035322 0.081629 Pclass -0.035144 -0.338481 1.000000 -0.369226 0.083081 0.018443 Age 0.036847 -0.077221 -0.369226 1.000000 -0.308247 -0.189119 SibSp -0.057527 -0.035322 0.083081 -0.308247 1.000000 0.414838 Parch -0.001652 0.081629 0.018443 -0.189119 0.414838 1.000000 Fare 0.012658 0.257307 -0.549500 0.096067 0.159651 0.216225 Fare PassengerId 0.012658 Survived 0.257307 Pclass -0.549500 Age 0.096067 SibSp 0.159651 Parch 0.216225 Fare 1.000000
本篇內容是真的有點長,各位慢慢看吧,小編就先溜了~~~
示例程式碼
老規矩,所有的示例程式碼都會上傳至程式碼管理倉庫 Github 和 Gitee 上,方便大家取用。
參考
https://baike.baidu.com/item/%E5%88%86%E4%BD%8D%E6%95%B0/10064158?fr=aladdin
https://blog.csdn.net/walking_visitor/article/details/85128461