(七)pandas知识学习2-python数据分析与机器学习实战
文章原创,最近更新:2018-05-3
1.数据排序
2.泰坦尼克案例
课程来源: python数据分析与机器学习实战-唐宇迪
为了方便大家学习,将练习所涉及的练习food_info.csv/titanic_train.csv文件以百度网盘共享的方式分享出来,
链接: https://pan.baidu.com/s/1HkYAj-T7Bj8mCx5N_GJUpQ 密码: 4ayh
1.数据排序
用.sort_values(columns)默认对某一列进行从小到大的排序,对数据进行排序,用到了sort_values,by参数可以指定根据哪一列数据进行排序。ascending是设置升序和降序。False就是降序,True就是升序.
sort_values其它参数:axis=0或者1 纵向排序还是横向; na_position='last' 将空值排在最后。kind和inplace是排序的具体方式,一般数据用不到。
具体案例如下,抽取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.泰坦尼克案例
泰坦尼克案例,是比较数据分析以及机器学习比较经典的入门案例,
- PassengerId的意思是对泰坦尼克号的每一个都进行了编号,总共有899个人
- Survived是指获救的人数.
- Pclass船的等级,有分一等舱,二等舱,三等舱.1代表一等舱,2代表二等舱,3代表三等舱.
- Name当前游客的姓名
- Sex当前游客的性别
- Age当前游客的年龄
- SibSp当前游客的兄弟姐妹数量,如果数值是1,则代表当前的兄弟姐妹的数量是1.
- Parch当前游客家里的老人总数
- Ticket当前船票的编码,这个具体对实际理解不是影响很大.
- Fare当前游客乘船的船票价格.跟船舱等级有挂钩的.
- Cabin船舱的编号,NAN是个缺失值.如果缺失值很多的情况下,大半情况下是不会用到这些数据.
- 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名的年龄,看一下年龄有什么有规律变化?
有个人24岁,还有2个比较小,年龄在2岁以及4岁.中间索引号为5的的是个NAN值,出现了缺失值,需要对缺失值进行处理.
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(),然而生成的却是所有数据的true/false矩阵.
如果显示false则不是缺失值,如果是true则是缺失值.,查看titanic_train.csv这个文件可知,索引为5的年龄在文件是空的,所以跟结果是一致的.
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的值会留下来,接下来打印的值会是怎么样的呢?我们看以下的结果:
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
如果操作的时候,不对缺失值进行处理,会产生什么样的结果呢?
首先我们来算一下平均年龄.平均年龄是由总的年龄除以总的人数,具体如下:
mean_age=sum(titanic_survival["Age"])/len(titanic_survival["Age"])
mean_age
Out[22]: nan
只要数据出现缺失值,数据就无法进行计算,需要用缺失值填充的手段,对数据进行计算.
其中的一种方法是,只对无缺失值的数据进行计算,有缺失值的去掉.
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
无缺失值是可以将结果计算出来的,如果有带缺失值,计算结果是无法计算出来的.
有没有一个函数,可以直接计算年龄的平均值,而不是需要传统的方法用总的年龄除以总的人数进行计算的呢?
可以用.mean()函数的方法可以直接计算.
collect_mean_age=titanic_survival["Age"].mean()
collect_mean_age
Out[29]: 29.69911764705882
其实直接将有缺失的值直接去掉的计算方法不是很好.一般缺失值采用的是平均值对缺失值进行填充,或者众数进行填充,这些都是比较常见的一个措施.
我们可以将缺失值补起来,使其成为一个完整的样本.
2.2pivot_table函数
船舱有1-3等级的船舱,求每个等级的船舱的平均价格?
先判断哪些人做的是一等舱的这些数据拿到手,然后用数据定位到船票价格的那一列,对当前的列求一个均值,求出平均的价格是多少.然后把一等舱的等级以及平均价格以字典的形式进行传入.然后再进行,二等舱,三等舱的价格传入.
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}
以上需求挺简单的,但是写的代码有点太过于麻烦,那有没有简单的操作可以快速的做一些数据统计的呢?
也许大多数人都有在Excel中使用数据透视表的经历,其实Pandas也提供了一个类似的功能,名为pivot_table。虽然pivot_table非常有用,但是我发现为了格式化输出我所需要的内容,经常需要记住它的使用语法。
用pivot_table函数就可以,关于具体定义如下:
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中的函数
- index: 索引
- columns: 可选的, 通过额外的方法来分割你所关心的实际值,然而aggfunc被应用到values上, aggfunc默认的是mean
具体案例,获取1-3等舱分别获救的人数?
指定了3个参数,index这个是指以谁为基准的,values指的是与Pclass之间相对应的关系,aggfunc就是计算index和values之间的关系,比如案列是平均数的关系.
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函数
想知道一个量与两个量之间的关系,应该怎么办?
具体案例,C/Q/S登船码头与总船票价格以及总救活的人数之间相对应的关系?
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=‘any’,按行,任意一行有NaN就整列丢弃 -
df.driopna(how='all')
一行中全部为NaN的,才丢弃 -
df.dropna(thresh=3)
保留至少3个非空值的行:一行中有3个值是非空的就保留
-
Age这列有缺失值,想把这些缺失值直接丢掉,可不可以?也是可以的,可以用dropna函数.
具体案例:将"Age","Sex"有出现缺失值的那一行,就将那一行丢掉.
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函数
想定位到具体的值,而不是一个样本,应该怎么办?
一个具体的值包含行号和列号,比如说定位到第84个样本中的"age"值是多少呢?
可以用.loc(a,b)函数,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函数
sort_values函数主要包含6个参数:
- columns=》要进行排序的列名称;
- ascending=》排序的方式true为升序,False为降序,默认为true;
- axis=》排序的轴,0表示index,1表示columns,当对数据列进行排序时,axis必须设置为0;
- inplace=》默认为False,表示对数据 表进行排序,不创建新实例;
- Kind=》可选择排序的方式,如快速排序等;
- na_position=》对NaN值的处理方式,可以选择first和last两种方式,默认为last,也就是将NaN值放在排序的结尾。
如何对年龄进行降序排列?
用sort_values函数可以实现.
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]
通过以上结果,我们可以看出,新的index是按之前的原始的index进行排序的.
2.6reset_index()函数
拓展:
reset_index可以还原索引,从新变为默认的整型索引
DataFrame.reset_index(level=None, drop=False, inplace=False, col_level=0, col_fill=”)
level控制了具体要还原的那个等级的索引
drop为False则索引列会被还原为普通列,否则会丢失
重新排序之后是否可以用新的index进行排序呢?并打印前10行的数据.
可以的,用reset_index()函数
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函数
apply 是 pandas 库的一个很重要的函数,多和 groupby 函数一起用,也可以直接用于 DataFrame 和 Series 对象。主要用于数据聚合运算,可以很方便的对分组进行现有的运算和自定义的运算。
pandas提供了很多丰富的函数,但是涉及到具体操作的时候,函数暂时满足不了,怎么执行这个东西?
解决的方法可以是通过写代码的方法慢慢拼接起来,也可以用apply函数进行自定义.
apply传进来是另外一个函数的名字.用法是先把一系列的操作写成函数的形式,然后再用apply传进这个函数,然后就可以在dataframe当中执行这个操作啦.
实例:我们定义了一个函数来返回第100行数据,就是想把这100行的数据返回出来.然后用apply这个定义函数,就可以将这100行的数据返出来.
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
统计每一列的缺失值个数是多少?
具体用法如下:
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等级,如何分别转化为"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函数的综合运用
获救人数与成年还是未成年的相互关系?
首先将之前的操作age_labels的数据拿过来新增加一列,然后把pivot_table函数把这个离散值进行一个处理.
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
计算的结果是adult/minor /unknown获救的一个平均值的结果是多少.