数据分析实际案例之:pandas在泰坦尼特号乘客数据中的使用
简介
1912年4月15日,号称永不沉没的泰坦尼克号因为和冰山相撞沉没了。因为没有足够的救援设备,2224个乘客中有1502个乘客不幸遇难。事故已经发生了,但是我们可以从泰坦尼克号中的历史数据中发现一些数据规律吗?今天本文将会带领大家灵活的使用pandas来进行数据分析。
泰坦尼特号乘客数据
我们从kaggle官网中下载了部分泰坦尼特号的乘客数据,主要包含下面几个字段:
| 变量名 | 含义 | 取值 |
|---|---|---|
| survival | 是否生还 | 0 = No, 1 = Yes |
| pclass | 船票的级别 | 1 = 1st, 2 = 2nd, 3 = 3rd |
| sex | 性别 | |
| Age | 年龄 | |
| sibsp | 配偶信息 | |
| parch | 父母或者子女信息 | |
| ticket | 船票编码 | |
| fare | 船费 | |
| cabin | 客舱编号 | |
| embarked | 登录的港口 | C = Cherbourg, Q = Queenstown, S = Southampton |
下载下来的文件是一个csv文件。接下来我们来看一下怎么使用pandas来对其进行数据分析。
使用pandas对数据进行分析
引入依赖包
本文主要使用pandas和matplotlib,所以需要首先进行下面的通用设置:
from numpy.random import randn
import numpy as np
np.random.seed(123)
import os
import matplotlib.pyplot as plt
import pandas as pd
plt.rc('figure', figsize=(10, 6))
np.set_printoptions(precision=4)
pd.options.display.max_rows = 20
读取和分析数据
pandas提供了一个read_csv方法可以很方便的读取一个csv数据,并将其转换为DataFrame:
path = '../data/titanic.csv'
df = pd.read_csv(path)
df
我们看下读入的数据:
| PassengerId | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 892 | 3 | Kelly, Mr. James | male | 34.5 | 0 | 0 | 330911 | 7.8292 | NaN | Q |
| 1 | 893 | 3 | Wilkes, Mrs. James (Ellen Needs) | female | 47.0 | 1 | 0 | 363272 | 7.0000 | NaN | S |
| 2 | 894 | 2 | Myles, Mr. Thomas Francis | male | 62.0 | 0 | 0 | 240276 | 9.6875 | NaN | Q |
| 3 | 895 | 3 | Wirz, Mr. Albert | male | 27.0 | 0 | 0 | 315154 | 8.6625 | NaN | S |
| 4 | 896 | 3 | Hirvonen, Mrs. Alexander (Helga E Lindqvist) | female | 22.0 | 1 | 1 | 3101298 | 12.2875 | NaN | S |
| 5 | 897 | 3 | Svensson, Mr. Johan Cervin | male | 14.0 | 0 | 0 | 7538 | 9.2250 | NaN | S |
| 6 | 898 | 3 | Connolly, Miss. Kate | female | 30.0 | 0 | 0 | 330972 | 7.6292 | NaN | Q |
| 7 | 899 | 2 | Caldwell, Mr. Albert Francis | male | 26.0 | 1 | 1 | 248738 | 29.0000 | NaN | S |
| 8 | 900 | 3 | Abrahim, Mrs. Joseph (Sophie Halaut Easu) | female | 18.0 | 0 | 0 | 2657 | 7.2292 | NaN | C |
| 9 | 901 | 3 | Davies, Mr. John Samuel | male | 21.0 | 2 | 0 | A/4 48871 | 24.1500 | NaN | S |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 408 | 1300 | 3 | Riordan, Miss. Johanna Hannah"" | female | NaN | 0 | 0 | 334915 | 7.7208 | NaN | Q |
| 409 | 1301 | 3 | Peacock, Miss. Treasteall | female | 3.0 | 1 | 1 | SOTON/O.Q. 3101315 | 13.7750 | NaN | S |
| 410 | 1302 | 3 | Naughton, Miss. Hannah | female | NaN | 0 | 0 | 365237 | 7.7500 | NaN | Q |
| 411 | 1303 | 1 | Minahan, Mrs. William Edward (Lillian E Thorpe) | female | 37.0 | 1 | 0 | 19928 | 90.0000 | C78 | Q |
| 412 | 1304 | 3 | Henriksson, Miss. Jenny Lovisa | female | 28.0 | 0 | 0 | 347086 | 7.7750 | NaN | S |
| 413 | 1305 | 3 | Spector, Mr. Woolf | male | NaN | 0 | 0 | A.5. 3236 | 8.0500 | NaN | S |
| 414 | 1306 | 1 | Oliva y Ocana, Dona. Fermina | female | 39.0 | 0 | 0 | PC 17758 | 108.9000 | C105 | C |
| 415 | 1307 | 3 | Saether, Mr. Simon Sivertsen | male | 38.5 | 0 | 0 | SOTON/O.Q. 3101262 | 7.2500 | NaN | S |
| 416 | 1308 | 3 | Ware, Mr. Frederick | male | NaN | 0 | 0 | 359309 | 8.0500 | NaN | S |
| 417 | 1309 | 3 | Peter, Master. Michael J | male | NaN | 1 | 1 | 2668 | 22.3583 | NaN | C |
418 rows × 11 columns
调用df的describe方法可以查看基本的统计信息:
| PassengerId | Pclass | Age | SibSp | Parch | Fare | |
|---|---|---|---|---|---|---|
| count | 418.000000 | 418.000000 | 332.000000 | 418.000000 | 418.000000 | 417.000000 |
| mean | 1100.500000 | 2.265550 | 30.272590 | 0.447368 | 0.392344 | 35.627188 |
| std | 120.810458 | 0.841838 | 14.181209 | 0.896760 | 0.981429 | 55.907576 |
| min | 892.000000 | 1.000000 | 0.170000 | 0.000000 | 0.000000 | 0.000000 |
| 25% | 996.250000 | 1.000000 | 21.000000 | 0.000000 | 0.000000 | 7.895800 |
| 50% | 1100.500000 | 3.000000 | 27.000000 | 0.000000 | 0.000000 | 14.454200 |
| 75% | 1204.750000 | 3.000000 | 39.000000 | 1.000000 | 0.000000 | 31.500000 |
| max | 1309.000000 | 3.000000 | 76.000000 | 8.000000 | 9.000000 | 512.329200 |
如果要想查看乘客登录的港口,可以这样选择:
df['Embarked'][:10]
0 Q
1 S
2 Q
3 S
4 S
5 S
6 Q
7 S
8 C
9 S
Name: Embarked, dtype: object
使用value_counts 可以对其进行统计:
embark_counts=df['Embarked'].value_counts()
embark_counts[:10]
S 270
C 102
Q 46
Name: Embarked, dtype: int64
从结果可以看出,从S港口登录的乘客有270个,从C港口登录的乘客有102个,从Q港口登录的乘客有46个。
同样的,我们可以统计一下age信息:
age_counts=df['Age'].value_counts()
age_counts.head(10)
前10位的年龄如下:
24.0 17
21.0 17
22.0 16
30.0 15
18.0 13
27.0 12
26.0 12
25.0 11
23.0 11
29.0 10
Name: Age, dtype: int64
计算一下年龄的平均数:
df['Age'].mean()
30.272590361445783
实际上有些数据是没有年龄的,我们可以使用平均数对其填充:
clean_age1 = df['Age'].fillna(df['Age'].mean())
clean_age1.value_counts()
可以看出平均数是30.27,个数是86。
30.27259 86
24.00000 17
21.00000 17
22.00000 16
30.00000 15
18.00000 13
26.00000 12
27.00000 12
25.00000 11
23.00000 11
..
36.50000 1
40.50000 1
11.50000 1
34.00000 1
15.00000 1
7.00000 1
60.50000 1
26.50000 1
76.00000 1
34.50000 1
Name: Age, Length: 80, dtype: int64
使用平均数来作为年龄可能不是一个好主意,还有一种办法就是丢弃平均数:
clean_age2=df['Age'].dropna()
clean_age2
age_counts = clean_age2.value_counts()
ageset=age_counts.head(10)
ageset
24.0 17
21.0 17
22.0 16
30.0 15
18.0 13
27.0 12
26.0 12
25.0 11
23.0 11
29.0 10
Name: Age, dtype: int64
图形化表示和矩阵转换
图形化对于数据分析非常有帮助,我们对于上面得出的前10名的age使用柱状图来表示:
import seaborn as sns
sns.barplot(x=ageset.index, y=ageset.values)

接下来我们来做一个复杂的矩阵变换,我们先来过滤掉age和sex都为空的数据:
cframe=df[df.Age.notnull() & df.Sex.notnull()]
cframe
| PassengerId | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 892 | 3 | Kelly, Mr. James | male | 34.5 | 0 | 0 | 330911 | 7.8292 | NaN | Q |
| 1 | 893 | 3 | Wilkes, Mrs. James (Ellen Needs) | female | 47.0 | 1 | 0 | 363272 | 7.0000 | NaN | S |
| 2 | 894 | 2 | Myles, Mr. Thomas Francis | male | 62.0 | 0 | 0 | 240276 | 9.6875 | NaN | Q |
| 3 | 895 | 3 | Wirz, Mr. Albert | male | 27.0 | 0 | 0 | 315154 | 8.6625 | NaN | S |
| 4 | 896 | 3 | Hirvonen, Mrs. Alexander (Helga E Lindqvist) | female | 22.0 | 1 | 1 | 3101298 | 12.2875 | NaN | S |
| 5 | 897 | 3 | Svensson, Mr. Johan Cervin | male | 14.0 | 0 | 0 | 7538 | 9.2250 | NaN | S |
| 6 | 898 | 3 | Connolly, Miss. Kate | female | 30.0 | 0 | 0 | 330972 | 7.6292 | NaN | Q |
| 7 | 899 | 2 | Caldwell, Mr. Albert Francis | male | 26.0 | 1 | 1 | 248738 | 29.0000 | NaN | S |
| 8 | 900 | 3 | Abrahim, Mrs. Joseph (Sophie Halaut Easu) | female | 18.0 | 0 | 0 | 2657 | 7.2292 | NaN | C |
| 9 | 901 | 3 | Davies, Mr. John Samuel | male | 21.0 | 2 | 0 | A/4 48871 | 24.1500 | NaN | S |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 403 | 1295 | 1 | Carrau, Mr. Jose Pedro | male | 17.0 | 0 | 0 | 113059 | 47.1000 | NaN | S |
| 404 | 1296 | 1 | Frauenthal, Mr. Isaac Gerald | male | 43.0 | 1 | 0 | 17765 | 27.7208 | D40 | C |
| 405 | 1297 | 2 | Nourney, Mr. Alfred (Baron von Drachstedt")" | male | 20.0 | 0 | 0 | SC/PARIS 2166 | 13.8625 | D38 | C |
| 406 | 1298 | 2 | Ware, Mr. William Jeffery | male | 23.0 | 1 | 0 | 28666 | 10.5000 | NaN | S |
| 407 | 1299 | 1 | Widener, Mr. George Dunton | male | 50.0 | 1 | 1 | 113503 | 211.5000 | C80 | C |
| 409 | 1301 | 3 | Peacock, Miss. Treasteall | female | 3.0 | 1 | 1 | SOTON/O.Q. 3101315 | 13.7750 | NaN | S |
| 411 | 1303 | 1 | Minahan, Mrs. William Edward (Lillian E Thorpe) | female | 37.0 | 1 | 0 | 19928 | 90.0000 | C78 | Q |
| 412 | 1304 | 3 | Henriksson, Miss. Jenny Lovisa | female | 28.0 | 0 | 0 | 347086 | 7.7750 | NaN | S |
| 414 | 1306 | 1 | Oliva y Ocana, Dona. Fermina | female | 39.0 | 0 | 0 | PC 17758 | 108.9000 | C105 | C |
| 415 | 1307 | 3 | Saether, Mr. Simon Sivertsen | male | 38.5 | 0 | 0 | SOTON/O.Q. 3101262 | 7.2500 | NaN | S |
332 rows × 11 columns
接下来使用groupby对age和sex进行分组:
by_sex_age = cframe.groupby(['Age', 'Sex'])
by_sex_age.size()
Age Sex
0.17 female 1
0.33 male 1
0.75 male 1
0.83 male 1
0.92 female 1
1.00 female 3
2.00 female 1
male 1
3.00 female 1
5.00 male 1
..
60.00 female 3
60.50 male 1
61.00 male 2
62.00 male 1
63.00 female 1
male 1
64.00 female 2
male 1
67.00 male 1
76.00 female 1
Length: 115, dtype: int64
使用unstack将Sex的列数据变成行:
| Sex | female | male |
|---|---|---|
| Age | ||
| 0.17 | 1.0 | 0.0 |
| 0.33 | 0.0 | 1.0 |
| 0.75 | 0.0 | 1.0 |
| 0.83 | 0.0 | 1.0 |
| 0.92 | 1.0 | 0.0 |
| 1.00 | 3.0 | 0.0 |
| 2.00 | 1.0 | 1.0 |
| 3.00 | 1.0 | 0.0 |
| 5.00 | 0.0 | 1.0 |
| 6.00 | 0.0 | 3.0 |
| ... | ... | ... |
| 58.00 | 1.0 | 0.0 |
| 59.00 | 1.0 | 0.0 |
| 60.00 | 3.0 | 0.0 |
| 60.50 | 0.0 | 1.0 |
| 61.00 | 0.0 | 2.0 |
| 62.00 | 0.0 | 1.0 |
| 63.00 | 1.0 | 1.0 |
| 64.00 | 2.0 | 1.0 |
| 67.00 | 0.0 | 1.0 |
| 76.00 | 1.0 | 0.0 |
79 rows × 2 columns
我们把同样age的人数加起来,然后使用argsort进行排序,得到排序过后的index:
indexer = agg_counts.sum(1).argsort()
indexer.tail(10)
Age
58.0 37
59.0 31
60.0 29
60.5 32
61.0 34
62.0 22
63.0 38
64.0 27
67.0 26
76.0 30
dtype: int64
从agg_counts中取出最后的10个,也就是最大的10个:
count_subset = agg_counts.take(indexer.tail(10))
count_subset=count_subset.tail(10)
count_subset
| Sex | female | male |
|---|---|---|
| Age | ||
| 29.0 | 5.0 | 5.0 |
| 25.0 | 1.0 | 10.0 |
| 23.0 | 5.0 | 6.0 |
| 26.0 | 4.0 | 8.0 |
| 27.0 | 4.0 | 8.0 |
| 18.0 | 7.0 | 6.0 |
| 30.0 | 6.0 | 9.0 |
| 22.0 | 10.0 | 6.0 |
| 21.0 | 3.0 | 14.0 |
| 24.0 | 5.0 | 12.0 |
上面的操作可以简化为下面的代码:
agg_counts.sum(1).nlargest(10)
Age
21.0 17.0
24.0 17.0
22.0 16.0
30.0 15.0
18.0 13.0
26.0 12.0
27.0 12.0
23.0 11.0
25.0 11.0
29.0 10.0
dtype: float64
将count_subset 进行stack操作,方便后面的画图:
stack_subset = count_subset.stack()
stack_subset
Age Sex
29.0 female 5.0
male 5.0
25.0 female 1.0
male 10.0
23.0 female 5.0
male 6.0
26.0 female 4.0
male 8.0
27.0 female 4.0
male 8.0
18.0 female 7.0
male 6.0
30.0 female 6.0
male 9.0
22.0 female 10.0
male 6.0
21.0 female 3.0
male 14.0
24.0 female 5.0
male 12.0
dtype: float64
stack_subset.name = 'total'
stack_subset = stack_subset.reset_index()
stack_subset
| Age | Sex | total | |
|---|---|---|---|
| 0 | 29.0 | female | 5.0 |
| 1 | 29.0 | male | 5.0 |
| 2 | 25.0 | female | 1.0 |
| 3 | 25.0 | male | 10.0 |
| 4 | 23.0 | female | 5.0 |
| 5 | 23.0 | male | 6.0 |
| 6 | 26.0 | female | 4.0 |
| 7 | 26.0 | male | 8.0 |
| 8 | 27.0 | female | 4.0 |
| 9 | 27.0 | male | 8.0 |
| 10 | 18.0 | female | 7.0 |
| 11 | 18.0 | male | 6.0 |
| 12 | 30.0 | female | 6.0 |
| 13 | 30.0 | male | 9.0 |
| 14 | 22.0 | female | 10.0 |
| 15 | 22.0 | male | 6.0 |
| 16 | 21.0 | female | 3.0 |
| 17 | 21.0 | male | 14.0 |
| 18 | 24.0 | female | 5.0 |
| 19 | 24.0 | male | 12.0 |
作图如下:
sns.barplot(x='total', y='Age', hue='Sex', data=stack_subset)

本文例子可以参考: https://github.com/ddean2009/learn-ai/
本文已收录于 http://www.flydean.com/01-pandas-titanic/
最通俗的解读,最深刻的干货,最简洁的教程,众多你不
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
数据分析实际案例之:pandas在泰坦尼特号乘客数据中的使用的更多相关文章
- Kaggle初体验之泰坦尼特生存预测
Kaggle初体验之泰坦尼特生存预测 学习完了决策树的ID3.C4.5.CART算法,找一个试手的地方,Kaggle的练习赛泰坦尼特很不错,记录下 流程 首先注册一个账号,然后在顶部菜单栏Co ...
- 万字长文,Python数据分析实战,使用Pandas进行数据分析
文章目录 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那么针对这三类人,我给大家 ...
- 利用Python进行数据分析 第5章 pandas入门(2)
5.2 基本功能 (1)重新索引 - 方法reindex 方法reindex是pandas对象地一个重要方法,其作用是:创建一个新对象,它地数据符合新地索引. 如,对下面的Series数据按新索引进行 ...
- 数据分析面试题之Pandas中的groupby
昨天晚上,笔者有幸参加了一场面试,有一个环节就是现场编程!题目如下: 示例数据如下,求每名学生(ID)对应的成绩(score)最高的那门科目(class)与ID,用Python实现: 这个题目 ...
- Python数据分析入门案例
转载自 https://blog.csdn.net/lijinlon/article/details/81517699 Data analysis by Python 入门 1. 重复数据处理 在Da ...
- 利用Python进行数据分析 第5章 pandas入门(1)
pandas库,含有使数据清洗和分析工作变得更快更简单的数据结构和操作工具.pandas是基于NumPy数组构建. pandas常结合数值计算工具NumPy和SciPy.分析库statsmodels和 ...
- Pandas之:Pandas高级教程以铁达尼号真实数据为例
Pandas之:Pandas高级教程以铁达尼号真实数据为例 目录 简介 读写文件 DF的选择 选择列数据 选择行数据 同时选择行和列 使用plots作图 使用现有的列创建新的列 进行统计 DF重组 简 ...
- Pandas高级教程之:处理缺失数据
目录 简介 NaN的例子 整数类型的缺失值 Datetimes 类型的缺失值 None 和 np.nan 的转换 缺失值的计算 使用fillna填充NaN数据 使用dropna删除包含NA的数据 插值 ...
- 《利用python进行数据分析》读书笔记--第十一章 金融和经济数据应用(一)
自2005年开始,python在金融行业中的应用越来越多,这主要得益于越来越成熟的函数库(NumPy和pandas)以及大量经验丰富的程序员.许多机构发现python不仅非常适合成为交互式的分析环境, ...
随机推荐
- Linux环境下的Docker的安装和部署、学习-一
CentOS Docker 安装Docker支持以下的CentOS版本:CentOS 7 (64-bit)CentOS 6.5 (64-bit) 或更高的版本 前提条件目前,CentOS 仅发行版本中 ...
- idea同时启动多个微服务模块进行管理
1,打开IDEA项目中的 .idea 下 的workspace.xml 找到文件中的 RunDashboard 配置块,增加如下圈起来的地方 代码: <option name="con ...
- Java类与对象的创建
以类的方式组织代码,以对象的方式组织(封装)数据 组织代码(类) public class Demo04 { String name;//默认值null int age;//默认值0 public v ...
- 今天太开心了,因为我知道了seastar框架
今天听说了一个新的C++语言开发的网络框架,叫做seastar. seastar有何特别之处呢?先看看官网提供的性能数据: 性能 HTTPD benchmark: cpu # request/sec ...
- 【记录一个问题】golang中copy []byte类型的slice无效,为什么?
有这样一段代码: src := []byte{xxxxx} dst := make([]byte, 0, len(src)) copy(dst, src) //这一行居然没生效! // dst = a ...
- azure flask 测试
本机 flask on linux service 完美.选择部署槽 web app service
- limit概述
5.limit 5.1.limit是将查询结果集的一部分取出来,通常使用在分页查询中 分页作用是为了提高用户体验,可以一页一页翻页看 5.2.limit用法:(非常重要) 完整用法:limit sta ...
- json模块 os模块 文件加密
目录 一:random随机模块 二:os模块 三:文件处理选择任意视频 四:sys模块 五:实现文件执行加密操作 六:json 序列化模块 七:json序列化 反序列化 八:json 文件写读方式 九 ...
- 用c#实现编写esp32单片机获取DHT11温度传感器参数
欢迎爱好c#的爱好者,本文章我们将用C#的nanoframework框架来编写获取esp32单片机上的DHT11传感器的温度和湿度 实现我们需要准备配置好esp32的环境可以看看之前写的esp32搭建 ...
- java 中的多线程简单介绍
package com.zxf.demo; /* * 多线程的实现方式两种? * 一..实现 runnable 接口 * 2.重写run方法 Run():当一个线程启动后,就会自动执行该方法 * 3. ...