复习:在前面我们已经学习了Pandas基础,知道利用Pandas读取csv数据的增删查改,今天我们要学习的就是探索性数据分析,主要介绍如何利用Pandas进行排序、算术计算以及计算描述函数describe()的使用。
【笔者注】该教程第一章第三部分感觉和前两部分有不小的区别
目录1 第一章:探索性数据分析
开始之前,导入numpy、pandas包和数据
In [1]:
#加载所需的库
import numpy as np
import pandas as pd
In [2]:
#载入之前保存的train_chinese.csv数据,关于泰坦尼克号的任务,我们就使用这个数据
df=pd.read_csv('train_chinese.csv')
pd.options.display.max_rows=6
df
Out[2]:
乘客ID | 是否幸存 | 仓位等级 | 姓名 | 性别 | 年龄 | 兄弟姐妹个数 | 父母子女个数 | 船票信息 | 票价 | 客舱 | 登船港口 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
888 | 889 | 0 | 3 | Johnston, Miss. Catherine Helen "Carrie" | female | NaN | 1 | 2 | W./C. 6607 | 23.4500 | NaN | S |
889 | 890 | 1 | 1 | Behr, Mr. Karl Howell | male | 26.0 | 0 | 0 | 111369 | 30.0000 | C148 | C |
890 | 891 | 0 | 3 | Dooley, Mr. Patrick | male | 32.0 | 0 | 0 | 370376 | 7.7500 | NaN | Q |
891 rows × 12 columns
1.6 了解你的数据吗?
教材《Python for Data Analysis》第五章
1.6.1 任务一:利用Pandas对示例数据进行排序,要求升序
具体请看《利用Python进行数据分析》第五章 排序和排名 部分。
先构建一个都为数字的DataFrame对象
In [3]:
dfTmp=pd.DataFrame(np.random.randint(0,10,size=(4,4)),index=[2,1,0,3],columns=['d','a','b','c'])
dfTmp
Out[3]:
d | a | b | c | |
---|---|---|---|---|
2 | 7 | 1 | 9 | 1 |
1 | 9 | 4 | 1 | 1 |
0 | 0 | 0 | 8 | 2 |
3 | 1 | 6 | 3 | 2 |
【问题】:大多数时候我们都是想根据列的值来排序,所以将你构建的DataFrame中的数据根据某一列,升序排列
使用DataFrame
对象的sort_values
方法,by
参数用来指定关键字是哪个或哪些字段,ascending
参数用来决定是否升序。
以下的排序函数均保持inplace
参数为默认值False
,不写回原对象。
In [4]:
dfTmp.sort_values(by=['d'],ascending=True)
Out[4]:
d | a | b | c | |
---|---|---|---|---|
0 | 0 | 0 | 8 | 2 |
3 | 1 | 6 | 3 | 2 |
2 | 7 | 1 | 9 | 1 |
1 | 9 | 4 | 1 | 1 |
【思考】通过书本你能说出Pandas对DataFrame数据的其他排序方式吗?
【总结】下面将不同的排序方式做一个总结
- 让行索引升序排序
In [5]:
dfTmp.sort_index(axis=0)
Out[5]:
d | a | b | c | |
---|---|---|---|---|
0 | 0 | 0 | 8 | 2 |
1 | 9 | 4 | 1 | 1 |
2 | 7 | 1 | 9 | 1 |
3 | 1 | 6 | 3 | 2 |
- 让列索引升序排序
In [6]:
dfTmp.sort_index(axis=1)
Out[6]:
a | b | c | d | |
---|---|---|---|---|
2 | 1 | 9 | 1 | 7 |
1 | 4 | 1 | 1 | 9 |
0 | 0 | 8 | 2 | 0 |
3 | 6 | 3 | 2 | 1 |
- 让列索引降序排序
In [7]:
dfTmp.sort_index(axis=1,ascending=False)
Out[7]:
d | c | b | a | |
---|---|---|---|---|
2 | 7 | 1 | 9 | 1 |
1 | 9 | 1 | 1 | 4 |
0 | 0 | 2 | 8 | 0 |
3 | 1 | 2 | 3 | 6 |
- 任选两列数据,分别作为第一关键字和第二关键字,均降序排序
原文此处表述如下
让任选两列数据同时降序排序
笔者认为“同时降序排序”不够准确,故做了修改。
In [8]:
dfTmp.sort_values(by=['b','d'],ascending=False)
Out[8]:
d | a | b | c | |
---|---|---|---|---|
2 | 7 | 1 | 9 | 1 |
0 | 0 | 0 | 8 | 2 |
3 | 1 | 6 | 3 | 2 |
1 | 9 | 4 | 1 | 1 |
1.6.2 任务二:对泰坦尼克号数据(trian.csv)按票价和年龄两列进行综合排序(降序排列),从这个数据中你可以分析出什么?
In [9]:
#票价最高的20人中的幸存人数
df.sort_values(by=['票价'],ascending=False).head(20).是否幸存.sum()
Out[9]:
14
In [10]:
#票价最低的20人中的幸存人数
df.sort_values(by=['票价']).head(20).是否幸存.sum()
Out[10]:
1
【原文思考】排序后,如果我们仅仅关注年龄和票价两列。根据常识我知道发现票价越高的应该客舱越好,所以我们会明显看出,票价前20的乘客中存活的有14人,这是相当高的一个比例,那么我们后面是不是可以进一步分析一下票价和存活之间的关系,年龄和存活之间的关系呢?当你开始发现数据之间的关系了,数据分析就开始了。
【笔者思考】正如上面所说,票价和存活有很大关系,票价前20的乘客中存活了14人,票价最低的20人中存活了1人。另一方面,日常生活中,票价在很大程度上还和乘船区间长度有关,需要把登船港口
字段考虑在内,但缺失下船港口的数据,所以暂时不能看出乘船区间长度。
多做几个数据的排序
In [11]:
#年龄最小的20人中的幸存人数
df.sort_values(by=['年龄']).head(10).是否幸存.sum()
Out[11]:
9
In [12]:
#年龄最大的20人中的幸存人数
df.sort_values(by=['年龄']).tail(10).是否幸存.sum()
Out[12]:
2
看来机会在很大程度上留给了孩子、年轻人。
1.6.3 任务三:利用Pandas进行算术计算,计算两个DataFrame数据相加结果
具体请看《利用Python进行数据分析》第五章 算术运算与数据对齐 部分
In [13]:
df1=pd.DataFrame(np.random.randint(0,10,size=(4,4)),index=[0,1,2,3],columns=['a','b','c','d'])
df1
Out[13]:
a | b | c | d | |
---|---|---|---|---|
0 | 8 | 8 | 2 | 9 |
1 | 8 | 9 | 4 | 8 |
2 | 0 | 5 | 0 | 0 |
3 | 3 | 1 | 7 | 6 |
In [14]:
df2=pd.DataFrame(np.random.randint(0,10,size=(4,4)),index=[1,2,3,4],columns=['a','b','e','f'])
df2
Out[14]:
a | b | e | f | |
---|---|---|---|---|
1 | 4 | 1 | 5 | 6 |
2 | 5 | 9 | 2 | 4 |
3 | 3 | 6 | 0 | 9 |
4 | 6 | 6 | 9 | 1 |
将frame_a和frame_b进行相加
In [15]:
df1+df2
Out[15]:
a | b | c | d | e | f | |
---|---|---|---|---|---|---|
0 | NaN | NaN | NaN | NaN | NaN | NaN |
1 | 12.0 | 10.0 | NaN | NaN | NaN | NaN |
2 | 5.0 | 14.0 | NaN | NaN | NaN | NaN |
3 | 6.0 | 7.0 | NaN | NaN | NaN | NaN |
4 | NaN | NaN | NaN | NaN | NaN | NaN |
【提醒】两个DataFrame相加后,会返回一个新的DataFrame,对应的行和列的值会相加,没有对应的会变成空值NaN。
当然,DataFrame还有很多算术运算,如减法,除法等,有兴趣的同学可以看《利用Python进行数据分析》第五章 算术运算与数据对齐 部分,多在网络上查找相关学习资料。
1.6.4 任务四:通过泰坦尼克号数据如何计算出在船上最大的家族有多少人?
【提醒】我们只需找出”兄弟姐妹个数“和”父母子女个数“之和最大的数
In [16]:
# 计算家族人数并写回df
df['家族人数']=df['兄弟姐妹个数']+df['父母子女个数']
In [17]:
df.sort_values(by=['家族人数']).iloc[-1].家族人数
Out[17]:
10
答案用了一种更快的方法,假设后续分析不需要家族人数的信息,就不用将计算结果写回。代码如下:
In [18]:
max(df['兄弟姐妹个数']+df['父母子女个数'])
Out[18]:
10
1.6.5 任务五:学会使用Pandas describe()函数查看数据基本统计信息
In [19]:
df1
Out[19]:
a | b | c | d | |
---|---|---|---|---|
0 | 8 | 8 | 2 | 9 |
1 | 8 | 9 | 4 | 8 |
2 | 0 | 5 | 0 | 0 |
3 | 3 | 1 | 7 | 6 |
In [20]:
pd.options.display.max_rows=20
df1.describe()
Out[20]:
a | b | c | d | |
---|---|---|---|---|
count | 4.000000 | 4.000000 | 4.000000 | 4.000000 |
mean | 4.750000 | 5.750000 | 3.250000 | 5.750000 |
std | 3.947573 | 3.593976 | 2.986079 | 4.031129 |
min | 0.000000 | 1.000000 | 0.000000 | 0.000000 |
25% | 2.250000 | 4.000000 | 1.500000 | 4.500000 |
50% | 5.500000 | 6.500000 | 3.000000 | 7.000000 |
75% | 8.000000 | 8.250000 | 4.750000 | 8.250000 |
max | 8.000000 | 9.000000 | 7.000000 | 9.000000 |
1.6.6 任务六:分别看看泰坦尼克号数据集中 票价、父母子女个数 的基本统计数据,你能发现什么?
In [21]:
df.describe()
Out[21]:
乘客ID | 是否幸存 | 仓位等级 | 年龄 | 兄弟姐妹个数 | 父母子女个数 | 票价 | 家族人数 | |
---|---|---|---|---|---|---|---|---|
count | 891.000000 | 891.000000 | 891.000000 | 714.000000 | 891.000000 | 891.000000 | 891.000000 | 891.000000 |
mean | 446.000000 | 0.383838 | 2.308642 | 29.699118 | 0.523008 | 0.381594 | 32.204208 | 0.904602 |
std | 257.353842 | 0.486592 | 0.836071 | 14.526497 | 1.102743 | 0.806057 | 49.693429 | 1.613459 |
min | 1.000000 | 0.000000 | 1.000000 | 0.420000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
25% | 223.500000 | 0.000000 | 2.000000 | 20.125000 | 0.000000 | 0.000000 | 7.910400 | 0.000000 |
50% | 446.000000 | 0.000000 | 3.000000 | 28.000000 | 0.000000 | 0.000000 | 14.454200 | 0.000000 |
75% | 668.500000 | 1.000000 | 3.000000 | 38.000000 | 1.000000 | 0.000000 | 31.000000 | 1.000000 |
max | 891.000000 | 1.000000 | 3.000000 | 80.000000 | 8.000000 | 6.000000 | 512.329200 | 10.000000 |
【笔者思考】从上面数据我们可以看出,有几乎80%的乘客的票价不高于平均值,票价不高的人很多,票价很高的人很少,如果假设大家的乘船区间长度对票价影响小,舱位等级对票价影响大,那么可以看出乘客的贫富差距较大。绝大对数人的父母子女个数为0,可能是登记时处于隐私考虑,隐瞒了真实数据。
【原文思考】从上面数据我们可以看出, 一共有891个票价数据, 平均值约为:32.20, 标准差约为49.69,说明票价波动特别大, 25%的人的票价是低于7.91的,50%的人的票价低于14.45,75%的人的票价低于31.00, 票价最大值约为512.33,最小值为0。
多做几个组数据的统计,看看你能分析出什么?
【笔者思考】
- 平均幸存率约为38.4%,非常惨烈;
- 登记了年龄的乘客的平均年龄约30岁,有一半的乘客低于28岁,只有四分之一的乘客高于38岁,说明乘客总体偏年轻。
【总结】本节中我们通过Pandas的一些内置函数对数据进行了初步统计查看,这个过程最重要的不是大家得掌握这些函数,而是看懂从这些函数出来的数据,构建自己的数据分析思维,这也是第一章最重要的点,希望大家学完第一章能对数据有个基本认识,了解自己在做什么,为什么这么做,后面的章节我们将开始对数据进行清洗,进一步分析。