文章原創(chuàng),最近更新:2018-05-3
1.數(shù)據(jù)排序
2.泰坦尼克案例
課程來源: python數(shù)據(jù)分析與機器學習實戰(zhàn)-唐宇迪
為了方便大家學習,將練習所涉及的練習food_info.csv/titanic_train.csv文件以百度網(wǎng)盤共享的方式分享出來,
鏈接: https://pan.baidu.com/s/1HkYAj-T7Bj8mCx5N_GJUpQ 密碼: 4ayh
1.數(shù)據(jù)排序
用.sort_values(columns)默認對某一列進行從小到大的排序,對數(shù)據(jù)進行排序,用到了sort_values,by參數(shù)可以指定根據(jù)哪一列數(shù)據(jù)進行排序。ascending是設置升序和降序。False就是降序,True就是升序.
sort_values其它參數(shù):axis=0或者1 縱向排序還是橫向; na_position='last' 將空值排在最后。kind和inplace是排序的具體方式,一般數(shù)據(jù)用不到。
具體案例如下,抽取Sodium_(mg),進行從小到大的排序.
import pandas
food_info=pandas.read_csv("food_info.csv")
food_info.sort_values("Sodium_(mg)",inplace=True)
food_info["Sodium_(mg)"]
Out[4]:
2 2
14 308
12 344
11 364
13 372
15 406
4 560
10 604
5 629
0 643
8 644
1 659
7 690
9 700
6 842
3 1146
Name: Sodium_(mg), dtype: int64
如果將抽取Sodium_(mg),進行從大到小的排序.又如何呢?
ascending默認是True,是從小到大的排序,需要設置成False,會變成從大到小的排序.
food_info.sort_values("Sodium_(mg)",inplace=True,ascending=False)
food_info["Sodium_(mg)"]
Out[6]:
3 1146
6 842
9 700
7 690
1 659
8 644
0 643
5 629
10 604
4 560
15 406
13 372
11 364
12 344
14 308
2 2
Name: Sodium_(mg), dtype: int64
2.泰坦尼克案例
泰坦尼克案例,是比較數(shù)據(jù)分析以及機器學習比較經(jīng)典的入門案例,
- PassengerId的意思是對泰坦尼克號的每一個都進行了編號,總共有899個人
- Survived是指獲救的人數(shù).
- Pclass船的等級,有分一等艙,二等艙,三等艙.1代表一等艙,2代表二等艙,3代表三等艙.
- Name當前游客的姓名
- Sex當前游客的性別
- Age當前游客的年齡
- SibSp當前游客的兄弟姐妹數(shù)量,如果數(shù)值是1,則代表當前的兄弟姐妹的數(shù)量是1.
- Parch當前游客家里的老人總數(shù)
- Ticket當前船票的編碼,這個具體對實際理解不是影響很大.
- Fare當前游客乘船的船票價格.跟船艙等級有掛鉤的.
- Cabin船艙的編號,NAN是個缺失值.如果缺失值很多的情況下,大半情況下是不會用到這些數(shù)據(jù).
- Embarked指的是當前游客登船的碼頭地點,是S登入口,還是C登入口,還是Q登入口
2.1缺失值的處理
import pandas as pd
titanic_survival=pd.read_csv("titanic_train.csv")
titanic_survival.head()
Out[9]:
PassengerId Survived Pclass \
0 1 0 3
1 2 1 1
2 3 1 3
3 4 1 1
4 5 0 3
Name Sex Age SibSp \
0 Braund, Mr. Owen Harris male 22.0 1
1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1
2 Heikkinen, Miss. Laina female 26.0 0
3 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1
4 Allen, Mr. William Henry male 35.0 0
Parch Ticket Fare Cabin Embarked
0 0 A/5 21171 7.2500 NaN S
1 0 PC 17599 71.2833 C85 C
2 0 STON/O2. 3101282 7.9250 NaN S
3 0 113803 53.1000 C123 S
4 0 373450 8.0500 NaN S
先觀察年齡這一列,先將年齡這一列打印出來,
titanic_survival["Age"]
Out[11]:
0 22.0
1 38.0
2 26.0
3 35.0
4 35.0
...
881 33.0
882 22.0
883 28.0
884 25.0
885 39.0
886 27.0
887 19.0
888 NaN
889 26.0
890 32.0
Name: Age, Length: 891, dtype: float64
查看前10名的年齡,看一下年齡有什么有規(guī)律變化?
有個人24歲,還有2個比較小,年齡在2歲以及4歲.中間索引號為5的的是個NAN值,出現(xiàn)了缺失值,需要對缺失值進行處理.
titanic_survival["Age"].loc[0:10]
Out[12]:
0 22.0
1 38.0
2 26.0
3 35.0
4 35.0
5 NaN
6 54.0
7 2.0
8 27.0
9 14.0
10 4.0
Name: Age, dtype: float64
接下來對缺失值進行處理,首先要判斷是否為缺失值?
拓展,以下是NA的處理方法"
python pandas判斷缺失值一般采用 isnull(),然而生成的卻是所有數(shù)據(jù)的true/false矩陣.
如果顯示false則不是缺失值,如果是true則是缺失值.,查看titanic_train.csv這個文件可知,索引為5的年齡在文件是空的,所以跟結(jié)果是一致的.
age_isnull=pd.isnull(age)
age_isnull
Out[16]:
0 False
1 False
2 False
3 False
4 False
5 True
6 False
882 False
883 False
884 False
885 False
886 False
887 False
888 True
889 False
890 False
Name: Age, Length: 891, dtype: bool
獲得的true/false的缺失值有什么作用呢?可以將true/false當成一個索引,可以將age_isnull傳入到age,對ture的值會留下來,接下來打印的值會是怎么樣的呢?我們看以下的結(jié)果:
age_null_true=age[age_isnull]
age_null_true
Out[18]:
5 NaN
17 NaN
19 NaN
26 NaN
28 NaN
29 NaN
31 NaN
..
846 NaN
849 NaN
859 NaN
863 NaN
868 NaN
878 NaN
888 NaN
Name: Age, Length: 177, dtype: float64
那缺失值一共有多少個呢?
缺失值177個是
age_null_count=len(age_null_true)
age_null_count
Out[20]: 177
如果操作的時候,不對缺失值進行處理,會產(chǎn)生什么樣的結(jié)果呢?
首先我們來算一下平均年齡.平均年齡是由總的年齡除以總的人數(shù),具體如下:
mean_age=sum(titanic_survival["Age"])/len(titanic_survival["Age"])
mean_age
Out[22]: nan
只要數(shù)據(jù)出現(xiàn)缺失值,數(shù)據(jù)就無法進行計算,需要用缺失值填充的手段,對數(shù)據(jù)進行計算.
其中的一種方法是,只對無缺失值的數(shù)據(jù)進行計算,有缺失值的去掉.
good_ages=titanic_survival["Age"][age_isnull==False]
good_ages
Out[24]:
0 22.0
1 38.0
2 26.0
3 35.0
4 35.0
6 54.0
7 2.0
881 33.0
882 22.0
883 28.0
884 25.0
885 39.0
886 27.0
887 19.0
889 26.0
890 32.0
Name: Age, Length: 714, dtype: float64
collect_mean_age=sum(good_ages)/len(good_ages)
collect_mean_age
Out[26]: 29.69911764705882
無缺失值是可以將結(jié)果計算出來的,如果有帶缺失值,計算結(jié)果是無法計算出來的.
有沒有一個函數(shù),可以直接計算年齡的平均值,而不是需要傳統(tǒng)的方法用總的年齡除以總的人數(shù)進行計算的呢?
可以用.mean()函數(shù)的方法可以直接計算.
collect_mean_age=titanic_survival["Age"].mean()
collect_mean_age
Out[29]: 29.69911764705882
其實直接將有缺失的值直接去掉的計算方法不是很好.一般缺失值采用的是平均值對缺失值進行填充,或者眾數(shù)進行填充,這些都是比較常見的一個措施.
我們可以將缺失值補起來,使其成為一個完整的樣本.
2.2pivot_table函數(shù)
船艙有1-3等級的船艙,求每個等級的船艙的平均價格?
先判斷哪些人做的是一等艙的這些數(shù)據(jù)拿到手,然后用數(shù)據(jù)定位到船票價格的那一列,對當前的列求一個均值,求出平均的價格是多少.然后把一等艙的等級以及平均價格以字典的形式進行傳入.然后再進行,二等艙,三等艙的價格傳入.
passenger_classes=[1,2,3]
fares_by_class={}
for this_class in passenger_classes:
pclass_rows=titanic_survival[titanic_survival["Pclass"]==this_class]
pclass_fares=pclass_rows["Fare"]
fare_for_class=pclass_fares.mean()
fares_by_class[this_class]=fare_for_class
fares_by_class
Out[42]: {1: 84.15468749999992, 2: 20.66218315217391, 3: 13.675550101832997}
以上需求挺簡單的,但是寫的代碼有點太過于麻煩,那有沒有簡單的操作可以快速的做一些數(shù)據(jù)統(tǒng)計的呢?
也許大多數(shù)人都有在Excel中使用數(shù)據(jù)透視表的經(jīng)歷,其實Pandas也提供了一個類似的功能,名為pivot_table。雖然pivot_table非常有用,但是我發(fā)現(xiàn)為了格式化輸出我所需要的內(nèi)容,經(jīng)常需要記住它的使用語法。
用pivot_table函數(shù)就可以,關(guān)于具體定義如下:
DataFrame.pivot_table(data, values=None, index=None, columns=None, aggfunc=’mean’, fill_value=None, margins=False, dropna=True, margins_name=’All’)
- data: DataFrame對象
- values: 顯示的列的名字,可以應用aggfunc中的函數(shù)
- index: 索引
- columns: 可選的, 通過額外的方法來分割你所關(guān)心的實際值,然而aggfunc被應用到values上, aggfunc默認的是mean
具體案例,獲取1-3等艙分別獲救的人數(shù)?
指定了3個參數(shù),index這個是指以誰為基準的,values指的是與Pclass之間相對應的關(guān)系,aggfunc就是計算index和values之間的關(guān)系,比如案列是平均數(shù)的關(guān)系.
passenger_survival = titanic_survival.pivot_table(index="Pclass", values="Survived", aggfunc=np.mean)
passenger_survival
Out[47]:
Survived
Pclass
1 0.629630
2 0.472826
3 0.242363
具體案例,獲取1-3等艙分別獲救的平均年齡?
aggfunc默認情況下是求平均值.
passenger_age = titanic_survival.pivot_table(index="Pclass", values="Age")
passenger_age
Out[49]:
Age
Pclass
1 38.233441
2 29.877630
3 25.140620
2.3driopna函數(shù)
想知道一個量與兩個量之間的關(guān)系,應該怎么辦?
具體案例,C/Q/S登船碼頭與總船票價格以及總救活的人數(shù)之間相對應的關(guān)系?
passenger_age = titanic_survival.pivot_table(index="Embarked", values=["Fare","Survived"],aggfunc=np.sum)
passenger_age
Out[52]:
Fare Survived
Embarked
C 10072.2962 93
Q 1022.2543 30
S 17439.3988 217
拓展:
- dropna() 丟棄缺失值
df.dropna()
df.dropna(axis=1)
默認axi=0,how=‘a(chǎn)ny’,按行,任意一行有NaN就整列丟棄df.driopna(how='all')
一行中全部為NaN的,才丟棄df.dropna(thresh=3)
保留至少3個非空值的行:一行中有3個值是非空的就保留
Age這列有缺失值,想把這些缺失值直接丟掉,可不可以?也是可以的,可以用dropna函數(shù).
具體案例:將"Age","Sex"有出現(xiàn)缺失值的那一行,就將那一行丟掉.
new_titanic_survival=titanic_survival.dropna(axis=0,subset=["Age","Sex"])
new_titanic_survival
Out[54]:
PassengerId Survived Pclass \
0 1 0 3
1 2 1 1
2 3 1 3
3 4 1 1
4 5 0 3
.. ... ... ...
885 886 0 3
886 887 0 2
887 888 1 1
889 890 1 1
890 891 0 3
Name Sex Age SibSp \
0 Braund, Mr. Owen Harris male 22.0 1
1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1
2 Heikkinen, Miss. Laina female 26.0 0
3 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1
4 Allen, Mr. William Henry male 35.0 0
.. ... ... ... ...
885 Rice, Mrs. William (Margaret Norton) female 39.0 0
886 Montvila, Rev. Juozas male 27.0 0
887 Graham, Miss. Margaret Edith female 19.0 0
889 Behr, Mr. Karl Howell male 26.0 0
890 Dooley, Mr. Patrick male 32.0 0
Parch Ticket Fare Cabin Embarked
0 0 A/5 21171 7.2500 NaN S
1 0 PC 17599 71.2833 C85 C
2 0 STON/O2. 3101282 7.9250 NaN S
3 0 113803 53.1000 C123 S
4 0 373450 8.0500 NaN S
.. ... ... ... ... ...
885 5 382652 29.1250 NaN Q
886 0 211536 13.0000 NaN S
887 0 112053 30.0000 B42 S
889 0 111369 30.0000 C148 C
890 0 370376 7.7500 NaN Q
[714 rows x 12 columns]
2.4loc函數(shù)
想定位到具體的值,而不是一個樣本,應該怎么辦?
一個具體的值包含行號和列號,比如說定位到第84個樣本中的"age"值是多少呢?
可以用.loc(a,b)函數(shù),a是索引好,b是列名,就可以獲取某個具體的值.
row_index_83_age=titanic_survival.loc[83,"Age"]
row_index_83_age
Out[56]: 28.0
其他類似的小練習:
row_index_1000_pclass=titanic_survival.loc[766,"Pclass"]
2.5sort_values函數(shù)
sort_values函數(shù)主要包含6個參數(shù):
- columns=》要進行排序的列名稱;
- ascending=》排序的方式true為升序,F(xiàn)alse為降序,默認為true;
- axis=》排序的軸,0表示index,1表示columns,當對數(shù)據(jù)列進行排序時,axis必須設置為0;
- inplace=》默認為False,表示對數(shù)據(jù) 表進行排序,不創(chuàng)建新實例;
- Kind=》可選擇排序的方式,如快速排序等;
- na_position=》對NaN值的處理方式,可以選擇first和last兩種方式,默認為last,也就是將NaN值放在排序的結(jié)尾。
如何對年齡進行降序排列?
用sort_values函數(shù)可以實現(xiàn).
new_titanic_survival=titanic_survival.sort_values("Age",ascending=False)
new_titanic_survival
Out[61]:
PassengerId Survived Pclass \
630 631 1 1
851 852 0 3
493 494 0 1
96 97 0 1
116 117 0 3
.. ... ... ...
859 860 0 3
863 864 0 3
868 869 0 3
878 879 0 3
888 889 0 3
Name Sex Age SibSp \
630 Barkworth, Mr. Algernon Henry Wilson male 80.0 0
851 Svensson, Mr. Johan male 74.0 0
493 Artagaveytia, Mr. Ramon male 71.0 0
96 Goldschmidt, Mr. George B male 71.0 0
116 Connors, Mr. Patrick male 70.5 0
.. ... ... ... ...
859 Razi, Mr. Raihed male NaN 0
863 Sage, Miss. Dorothy Edith "Dolly" female NaN 8
868 van Melkebeke, Mr. Philemon male NaN 0
878 Laleff, Mr. Kristo male NaN 0
888 Johnston, Miss. Catherine Helen "Carrie" female NaN 1
Parch Ticket Fare Cabin Embarked
630 0 27042 30.0000 A23 S
851 0 347060 7.7750 NaN S
493 0 PC 17609 49.5042 NaN C
96 0 PC 17754 34.6542 A5 C
116 0 370369 7.7500 NaN Q
.. ... ... ... ... ...
859 0 2629 7.2292 NaN C
863 2 CA. 2343 69.5500 NaN S
868 0 345777 9.5000 NaN S
878 0 349217 7.8958 NaN S
888 2 W./C. 6607 23.4500 NaN S
[891 rows x 12 columns]
通過以上結(jié)果,我們可以看出,新的index是按之前的原始的index進行排序的.
2.6reset_index()函數(shù)
拓展:
reset_index可以還原索引,從新變?yōu)槟J的整型索引
DataFrame.reset_index(level=None, drop=False, inplace=False, col_level=0, col_fill=”)
level控制了具體要還原的那個等級的索引
drop為False則索引列會被還原為普通列,否則會丟失
重新排序之后是否可以用新的index進行排序呢?并打印前10行的數(shù)據(jù).
可以的,用reset_index()函數(shù)
titanic_reindexed=new_titanic_survival.reset_index(drop=False)
titanic_reindexed.loc[0:10]
Out[64]:
index PassengerId Survived Pclass \
0 630 631 1 1
1 851 852 0 3
2 493 494 0 1
3 96 97 0 1
4 116 117 0 3
5 672 673 0 2
6 745 746 0 1
7 33 34 0 2
8 54 55 0 1
9 280 281 0 3
10 456 457 0 1
Name Sex Age SibSp Parch \
0 Barkworth, Mr. Algernon Henry Wilson male 80.0 0 0
1 Svensson, Mr. Johan male 74.0 0 0
2 Artagaveytia, Mr. Ramon male 71.0 0 0
3 Goldschmidt, Mr. George B male 71.0 0 0
4 Connors, Mr. Patrick male 70.5 0 0
5 Mitchell, Mr. Henry Michael male 70.0 0 0
6 Crosby, Capt. Edward Gifford male 70.0 1 1
7 Wheadon, Mr. Edward H male 66.0 0 0
8 Ostby, Mr. Engelhart Cornelius male 65.0 0 1
9 Duane, Mr. Frank male 65.0 0 0
10 Millet, Mr. Francis Davis male 65.0 0 0
Ticket Fare Cabin Embarked
0 27042 30.0000 A23 S
1 347060 7.7750 NaN S
2 PC 17609 49.5042 NaN C
3 PC 17754 34.6542 A5 C
4 370369 7.7500 NaN Q
5 C.A. 24580 10.5000 NaN S
6 WE/P 5735 71.0000 B22 S
7 C.A. 24579 10.5000 NaN S
8 113509 61.9792 B30 C
9 336439 7.7500 NaN Q
10 13509 26.5500 E38 S
2.7apply函數(shù)
apply 是 pandas 庫的一個很重要的函數(shù),多和 groupby 函數(shù)一起用,也可以直接用于 DataFrame 和 Series 對象。主要用于數(shù)據(jù)聚合運算,可以很方便的對分組進行現(xiàn)有的運算和自定義的運算。
pandas提供了很多豐富的函數(shù),但是涉及到具體操作的時候,函數(shù)暫時滿足不了,怎么執(zhí)行這個東西?
解決的方法可以是通過寫代碼的方法慢慢拼接起來,也可以用apply函數(shù)進行自定義.
apply傳進來是另外一個函數(shù)的名字.用法是先把一系列的操作寫成函數(shù)的形式,然后再用apply傳進這個函數(shù),然后就可以在dataframe當中執(zhí)行這個操作啦.
實例:我們定義了一個函數(shù)來返回第100行數(shù)據(jù),就是想把這100行的數(shù)據(jù)返回出來.然后用apply這個定義函數(shù),就可以將這100行的數(shù)據(jù)返出來.
def hundredth_row(column):
hundredth__item=column.loc[99]
return hundredth__item
hundredth_row=titanic_survival.apply(hundredth_row)
hundredth_row
Out[67]:
PassengerId 100
Survived 0
Pclass 2
Name Kantor, Mr. Sinai
Sex male
Age 34
SibSp 1
Parch 0
Ticket 244367
Fare 26
Cabin NaN
Embarked S
dtype: object
統(tǒng)計每一列的缺失值個數(shù)是多少?
具體用法如下:
def not_null_count(column):
column_null=pd.isnull(column)
null=column[column_null]
return len(null)
column_null_count=titanic_survival.apply(not_null_count)
column_null_count
Out[70]:
PassengerId 0
Survived 0
Pclass 0
Name 0
Sex 0
Age 177
SibSp 0
Parch 0
Ticket 0
Fare 0
Cabin 687
Embarked 2
dtype: int64
將船艙中的1-3等級,如何分別轉(zhuǎn)化為"First Class"/"Second Class"/"Three 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)
classes
Out[72]:
0 Third Class
1 First Class
2 Third Class
3 First Class
4 Third Class
886 Second Class
887 First Class
888 Third Class
889 First Class
890 Third Class
Length: 891, dtype: object
如何設置不同年齡的劃分,比如小于18,為minor(未成年)/大于18為adult(成年)
def generate_age_label(row):
age = row["Age"]
if pd.isnull(age):
return "unknown"
elif age < 18:
return "minor"
else:
return "adult"
age_labels = titanic_survival.apply(generate_age_label, axis=1)
age_labels
Out[78]:
0 adult
1 adult
2 adult
3 adult
4 adult
885 adult
886 adult
887 adult
888 unknown
889 adult
890 adult
Length: 891, dtype: object
2.8pivot_table函數(shù)的綜合運用
獲救人數(shù)與成年還是未成年的相互關(guān)系?
首先將之前的操作age_labels的數(shù)據(jù)拿過來新增加一列,然后把pivot_table函數(shù)把這個離散值進行一個處理.
titanic_survival['age_labels'] = age_labels
age_group_survival = titanic_survival.pivot_table(index="age_labels", values="Survived")
age_group_survival
Out[80]:
Survived
age_labels
adult 0.381032
minor 0.539823
unknown 0.293785
計算的結(jié)果是adult/minor /unknown獲救的一個平均值的結(jié)果是多少.