小丸子踏入python之路:python_day05(用Pandas處理泰坦尼克船員獲救數據titanic_train.csv)
泰坦尼克船員獲救數據:
titanic_train.csv
用excel打開數據集。顯示如下:
寫在前邊:
為了方便以後運用numpy和pandas的庫,分別造它們的別名np和pd.
import pandas as pd #造pandas的別名為pd
import numpy as np #造numpy的別名為np
一、讀取數據
import pandas as pd #造pandas的別名為pd
import numpy as np #造numpy的別名為np
#泰坦尼克號船員獲救數據
titanic_survival = pd.read_csv(" titanic_train.csv")
titanic_survival.head() #head()無參數,默認返回數據的前5行
運行結果:
二、對數據進行處理
1. 用 .isnull()來處理數據的缺失值
其實數據都有缺失值,在進行數據處理的時候首先對缺失值要有一個詳細的了解。
下邊將通過對列“age”列的處理來看一下缺失值的情況的。
用.isnull()可以返回缺失值的情況。若當前值缺失,返回true,否則返回false。
age = titanic_survival["Age"]
print(age.loc[0:10]) # 顯示age數據的0——10行
#用.isnull()對缺失值進行處理。若當前的值為一個缺失值,則返回true,否則返回false
age_is_null = pd.isnull(age)
print(age_is_null)
#將age_is_null的值為true的留下來,把age_is_null值為false的過濾掉
age_null_true = age[age_is_null]
print(age_null_true) #打印所有的缺失值
age_null_count = len(age_null_true) # 打印缺失值的個數
print("age屬性缺失值的個數: ",age_null_count)
運行結果:
2.缺失值的那點事
2.1 當不對缺失值進行處理的時候會有什麽後果呢?
為什麽要對缺失值進行處理?
打比方:
目標:現在想要求出船員的平均年齡。
過程:則對“Age”這列數據進行操作。用sum()函數求出船員的年齡總和。用len()求出樣本數據的長度,即船員的個數。
#目標:求船員的平均年齡
#過程:用sum()函數求出船員的年齡總和。用len()求出樣本數據的長度,即船員的個數
mean_age = sum(titanic_survival["Age"])/len(titanic_survival["Age"]) #船員的平均年齡
print("平均年齡 = ",mean_age) #打印平均年齡
那麽這樣的操作是否能得到我們想要的結果呢?
運行結果:
這樣的顯示結果是因為原本的“Age”數據中存在缺失值,而缺失值會被標記為NaN,所以參與運算後平均年齡的返回結果為NaN
2.2 如何對缺失值未處理造成的後果進行調整呢?
由2.1明顯的看出缺失值的錯在對數據的處理帶來的後果,那麽接下來,我們就用不同的方法對其進行解決。
2.2.1 直接過濾缺失值的辦法。
有第一節中,age_is_null的變量,我們得到了關於是否為缺失值的返回。
當其為缺失值的時候,age_is_null = True
但其不是缺失值的時候,age_is_null = False
#對上邊缺失值導致結果出不來的情況進行一個處理。
#最簡單的方法就是把有缺失值的直接去掉,只保留沒有缺失值的,並進行運算。
good_ages = titanic_survival["Age"][age_is_null == False]
#[age_is_null == False]若沒有缺失值,則保留。(由此濾去缺失值)
#print(good_ages)
correct_mean_age = sum(good_ages) / len(good_ages)
print("平均年齡 = ",correct_mean_age)
運行結果:
2.2.2 直接用pandas中提供的mean()方法來處理
correct_mean_age = titanic_survival["Age"].mean() #直接用Pandas中自帶的mean()函數求平均
print("用mean()得到的平均年齡 = ",correct_mean_age)
運行結果:
2.2.3 註意
其實直接濾去缺失值的樣本並不是一個很好的方法,其實我們可以拿年齡的平均數、中位數、重數進行一個填充。
3.求每類船艙對應的平均票價
3.1 用for循環的方式求出平均
要求:船艙等級一共有[1,2,3]三種,分別對應不同的票價,所以每一級船艙都有自己的平均票價。求每級船艙的平均票價。
過程:通過for循環對每一類船艙進去抽取,抽取出屬於同一類船艙等級的船客的全部信息,再從每一個分類船客中抽出“Fare”(船票價格)這列數據,對其用,mean()函數求平均,再返回給每一類的類別。
#船艙等級一共有3種,求每一種船艙等級對應的平均票價
passenger_classes = [1,2,3] #船艙等級用list列出[1,2,3]
fares_by_class = {} #定義空的字典,用來存放船艙等級以及對應的平均票價
for this_class in passenger_classes: #對每一類船艙進行循環
pclass_rows = titanic_survival[titanic_survival["Pclass"] == this_class] #當this_class = 1時,返回的是所有一等艙的船客的信息
#this_class = 2/3時同理
pclass_fares = pclass_rows["Fare"] #再從每次取得的信息中,返回“Fare”(票價)這列的數據
fare_for_class = pclass_fares.mean() #用.mean()對票價求平均
fares_by_class[this_class] = fare_for_class #將對應的平均票價傳給對應的船艙
print("每類船艙對應的平均票價 = ", fares_by_class)
運行結果:
3.2 用pandas自帶的函數.pivot_table()來統計船艙等級與平均票價的關系
看了3.1後發現,我們的需求很簡單,但是代碼實現起來並不是很簡便,那麽有沒有什麽Pandas自帶的方法來簡便的完成這類數據統計的操作呢?答案當然是肯定的啦,不然我怎麽會又開了3.2. 吼吼
.pivot_table() : 相當於一個數據透視表。
也相當於統計一個量與其他量之間關系的一個函數
.pivot_table()有三個參數:
index:表示接下來要統計的信息是以誰為基準的,index就 = 誰
values:表示用統計index與誰之間的關系,values就 = 誰
aggfunc:表示index與values之間的什麽關系,aggfunc就 = 什麽關系(不寫的話,默認求均值)
#用.pivot_table來統計Pclass和Fare之間的關系
#三個參數:index:表示接下來要統計的信息是以誰為基準的,index就=誰(每個船艙等級對應的平均票價,所以index = Pclass船艙等級)
# values:表示用統計Pclass與誰之間的關系,values就=誰(Pclass與票價之間的關系,values = Fare)
# aggfunc:表示Pclass與Fare之間的什麽關系,求的是船艙等級與票價的平均值之間的關系,所以aggfunc=np.mean()
passenger_classes = titanic_survival.pivot_table(index = "Pclass",values = "Fare",aggfunc = np.mean)
print(passenger_classes)
運行結果:
4.用.pivot_table()求每類船艙對應的平均存活率
#求每類船艙對應的存活率
#.pivot_table的三個參數:
#三個參數:index:表示接下來要統計的信息是以誰為基準的,index就=誰(每個船艙等級對應的平均存活率,所以index = Pclass船艙等級)
# values:表示用統計Pclass與誰之間的關系,values就=誰(Pclass與存活率之間的關系,values = Survived)
# aggfunc:表示Pclass與Survived之間的什麽關系,求的是船艙等級的平均存活率的關系,所以aggfunc=np.mean()
passenger_survical = titanic_survival.pivot_table(index = "Pclass",values = "Survived",aggfunc = np.mean)
print(passenger_survical)
運行結果:
5.用.pivot_table()求每類船艙對應的平均年齡
#求每類船艙對應的平均年齡
#.pivot_table的三個參數:
#三個參數:index:表示接下來要統計的信息是以誰為基準的,index就=誰(每個船艙等級對應的平均年齡,所以index = Pclass船艙等級)
# values:表示用統計Pclass與誰之間的關系,values就=誰(Pclass與年齡之間的關系,values = Age)
# aggfunc:表示Pclass與Age之間的什麽關系,求的是船艙等級的平均年齡的關系,所以aggfunc=np.mean()
passenger_age = titanic_survival.pivot_table(index = "Pclass",values = "Age",aggfunc = np.mean)
print(passenger_age)
運行結果:
6. 用.pivot_table()看一個量與其他兩個量之間的關系
需求:想要看不同的登船地點(C,Q,S)的總的票價和總的獲救人數。
過程:用.pivot_table()的話,對於index ,接下來要統計的東西是以登船地點為基準的,所以index = "Embarked"
對於values,要統計的是不同登船地點與票價和是否獲救之間的關系,所以values = ["Fare","Survived" ]
對於aggfunc,要統計的是不同登船地點的總的票價和總的獲救人數,所以aggfunc = np.sum
port_stats = titanic_survival.pivot_table(index = "Embarked",values = ["Fare","Survived"],aggfunc = np.sum)
print(port_stats)
運行結果:
7. 用.dropna()扔掉具有缺失值的行
#用.dropna扔掉具有缺失值的行
titanic_survival.head(7)
new_titanic_survival = titanic_survival.dropna(axis = 0,subset = ["Age","Sex"])
#看一些Age和Sex這兩列有沒有缺失值的,如果有,就把具有缺失值的這行數據扔掉。
titanic_survival.head(7)
#new_titanic_survival.head(7) #分別把drop前後的前7行數據看一下吧
運行結果:dropna之前的數據
註意:此打印的結果是不帶print的打印方式,因為帶有print的打印一行顯示不完,看起來不夠清楚。
dropna之後的數據
8. 用.loc()確定到每一個坐標上的數據
數據中每一個具體的值都是由一個行號和列名唯一確定的,所以完全可以用行號和列名來返回這個位置上的值。
#如何取確定位置上的一個數據
row_index_83_age = titanic_survival.loc[83,"Age"]
row_index_766_pclass = titanic_survival.loc[766,"Pclass"]
print("第83行的age = ",row_index_83_age)
print("第766行的pclass = ",row_index_766_pclass)
運行結果:
9.用.sort_values()進行數據的重新排序,並用.reset_index()重置排序後的index值(即行號)。
用.sort_values()對數據進行排序後,雖然行的順序因為排序條件發生了變化,但是其行號卻還保持著之前的樣子,為了讓排序後的數據的行號變成從0開始,依次增大,所以運用.reset_index()進行重置。
new_titanic_survival = titanic_survival.sort_values("Age",ascending = False) #根據“Age”的大小逆序排列。 #print(new_titanic_survival[0:10]) #打印未進行.reset_index時的數據前10行 titanic_reindexed = new_titanic_survival.reset_index(drop = True) #print(titanic_reindexed.loc[0:10]) new_titanic_survival[0:10]
titanic_reindexed.loc[0:10]
運行結果:
註意:此打印的結果是不帶print的打印方式,因為帶有print的打印一行顯示不完,看起來不夠清楚。
未進行.reset_index時的數據前10行
進行.reset_index後的數據前邊10行
10、apply(自定義函數名) 的功能
我們知道pandas已經提供了很多個功能強大的函數,但是還是會有一些具體的操作沒有辦法直接用已經定義的函數來完成的,此時我們應該如何執行這些呢?
一方面,可以通過寫代碼慢慢的拼接出來。
另一方面,可以通過寫apply()函數,而這個apply()函數就相當於我們可以進行一個自定義函數的操作。
在apply()中傳進來的是一個函數名,而傳進來的函數可以是自己定義的函數,即將自己的操作定義成一個函數的形式,然後apply一下,這時就會在這個DataFrame中執行這個操作了。
10.1 關於apply(自定義函數名) 的第一個例子
具體如下所示:
需求:我們想要返回數據集合的第100行數據。
過程:先定義一個返回第100行數據的函數hundredth_row ,然後在apply一下
#定義一個新的函數hundredth_row,用來返回第100行數據
def hundredth_row(column):
hundredth_item = column.loc[99]
return hundredth_item
hundredth_row = titanic_survival.apply(hundredth_row) #將新定義好的函數apply一下
print(hundredth_row)
運行結果:
10.2 關於apply(自定義函數名) 的第二個例子
用apply(自定義函數名)來得到每一個屬性缺失值的個數。
#返回所有屬性缺失值的個數
def isnull_count(column):
column_null = pd.isnull(column) #返回值是true或flase
null = column[column_null] #缺失值列表
return len(null)
column_null_count = titanic_survival.apply(isnull_count)
print(column_null_count)
運行結果:
10.3 關於apply(自定義函數名) 的第三個例子
用apply(自定義函數名)來對船艙等級【1,2,3】進行一個改寫,改成First Class,Second Class ,Third Class
#將船艙等級進行一個轉化,1——First Class....
def which_class(row):
pclass = row["Pclass"]
if pd.isnull(pclass):
return "UnKnown"
elif pclass == 1:
return "First Class"
elif pclass == 2:
return "Second Class"
elif pclass == 3:
return "Third Class"
classes = titanic_survival.apply(which_class,axis = 1)
print(classes)
運行結果:
10.4 關於apply(自定義函數名) 的第四個例子
將年齡離散化,在本實例數據集上的“Age”是一個連續的值,這裏以18為界限,將其離散化。
def generate_age_label(row):
age = row["Age"]
if pd.isnull(age):
return "Unknow"
elif age < 18:
return "minor"
else:
return "adult"
age_labels = titanic_survival.apply(generate_age_label, axis = 1)
print(age_labels)
運行結果:
友情贈送
利用上邊的自定義函數,使用.pivot_table()函數得到年齡階段與獲救率之間的關系。
titanic_survival["age_labels"] = age_labels #將上一個裏邊返回的關於age_labels的數據組合成數據的一列
#得到年齡階段與存活率之間的關系
age_group_survival = titanic_survival.pivot_table(index = "age_labels",values = "Survived")
print(age_group_survival)
運行結果:
小丸子踏入python之路:python_day05(用Pandas處理泰坦尼克船員獲救數據titanic_train.csv)