本系列博客为DataWhale第37期《动手学数据分析》课程学习笔记,课程以Kaggle上经典的泰坦尼克数据比赛为主线,从最基础的数据导入开始做数据分析实战。
比赛具体内容及数据获取链接如下:
Titanic - Machine Learning from Disaster | Kagglehttps://www.kaggle.com/competitions/titanic
目录
一、数据载入
导入numpy和pandas
import numpy as np
import pandas as pd
载入数据
绝对路径是指文件在硬盘上真正存在的路径。相对路径就是相对于自己的目标文件位置。
#使用相对路径载入数据(直接从project中导入数据)
df = pd.read_csv('train.csv')
df.head(3)
#当使用相对路径载入报错时,可使用os.getcwd()查看当前工作目录(但需导入os包)
#使用绝对路径载入数据
df = pd.read_csv(r'C:\Users\Wings\桌面\train.csv')
#因为windows下的目录字符串中的"\"在Python的字符串中有转义的作用,在路径前加r可以避免这个现象
【拓展】pd.read_csv()和pd.read_table()的不同
read_csv和read_table都是是加载带分隔符的数据,每一个分隔符作为一个数据的标志,但二者读出来的数据格式是不一样的。read_table以制表符\t作为数据的标志,也就是以行为单位进行存储,读取excel文件后每个字符串间有逗号相隔,这表明每一行(而不是每一个字符串)作为一个维度进行了存储。read_csv读取excel文件后虽然也是一个数组,但每一个字符串作为一列。
因此,设置sep=’\t’可以使pd.read_csv()实现pd.read_table()的功能;同样,设置sep=’,’能够让pd.read_table()实现pd.read_csv()的功能。
【拓展】'.tsv'和'.csv'的不同
tsv代表制表符分隔值(Tab-separated values),用制表符(Tab,'\t')作为字段值的分隔符。csv代表逗号分隔符(Comma-separated values),用半角逗号(',')作为字段值的分隔符。
逐块读取
当读取的文件较大时,直接利用pandas读取会给电脑造成过大的压力,逐块读取可避免该问题。
chunker = pd.read_csv('train.csv', chunksize=1000)
#chunkersize参数用来控制迭代数据分析的大小,作为每一个数据块的行数
for piece in chunker:
print(type(piece))
print(len(piece))
#chunker(数据块)类型为<class 'pandas.core.frame.DataFrame'>
#chunker(数据块)数量有891
利用chunkersize参数进行逐块加载,本质就是将文本分成若干块。每次处理chunkersize行的数据,最终返回一个TextParser对象,对该对象进行迭代遍历,完成逐块统计的合并处理。
更改表头
PassengerId | 乘客ID |
Survived | 是否幸存 |
Pclass | 乘客等级(1/2/3等舱位) |
Name | 乘客姓名 |
Sex | 性别 |
Age | 年龄 |
SibSp | 堂兄弟/妹个数 |
Parch | 父母与小孩个数 |
Ticket | 船票信息 |
Fare | 票价 |
Cabin | 客舱 |
Embarked | 登船港口 |
df = pd.read_csv('train.csv',
names=['乘客ID','是否幸存','仓位等级','姓名','性别','年龄','兄弟姐妹个数','父母子女个数','船票信息','票价','客舱','登船港口'],
index_col='乘客ID', header=0)
二、初步观察
#查看数据的基本信息
df.info()
# <class 'pandas.core.frame.DataFrame'>
# Int64Index: 891 entries, 1 to 891
# Data columns (total 11 columns):
# # Column Non-Null Count Dtype
# --- ------ -------------- -----
# 0 是否幸存 891 non-null int64
# 1 仓位等级 891 non-null int64
# 2 姓名 891 non-null object
# 3 性别 891 non-null object
# 4 年龄 714 non-null float64
# 5 兄弟姐妹个数 891 non-null int64
# 6 父母子女个数 891 non-null int64
# 7 船票信息 891 non-null object
# 8 票价 891 non-null float64
# 9 客舱 204 non-null object
# 10 登船港口 889 non-null object
# dtypes: float64(2), int64(4), object(5)
# memory usage: 83.5+ KB
#观察表格前10行的数据和后15行的数据
df.head(10)
df.tail(15)
#判断数据是否为空,为空的地方返回True,其余地方返回False
df.isnull().head()
三、保存数据
#将你加载并做出改变的数据在工作目录下保存为一个新文件
df.to_csv('train_chinese.csv')
不同的操作系统保存下来可能会有乱码,可以加入参数encoding='GBK'或encoding = 'utf-8'。
四、数据类型
DateFrame和Series
Series:
sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}
example_1 = pd.Series(sdata)
example_1
# Ohio 35000
# Texas 71000
# Oregon 16000
# Utah 5000
# dtype: int64
DataFrame:
dfdata = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'],
'year': [2000, 2001, 2002, 2001, 2002, 2003],
'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2]}
example_2 = pd.DataFrame(dfdata)
example_2
# state year pop
# 0 Ohio 2000 1.5
# 1 Ohio 2001 1.7
# 2 Ohio 2002 3.6
# 3 Nevada 2001 2.4
# 4 Nevada 2002 2.9
# 5 Nevada 2003 3.2
查看列及列名
查看列名
df = pd.read_csv('train.csv')
df.columns
# Index(['PassengerId', 'Survived', 'Pclass', 'Name', 'Sex', 'Age', 'SibSp',
# 'Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked'],
# dtype='object')
查看"Cabin"列所有值
df['Cabin'].head(3)
# 0 NaN
# 1 C85
# 2 NaN
# Name: Cabin, dtype: object
加载文件"test_1.csv",对比"train.csv",将多出的列删除
test_1 = pd.read_csv('test_1.csv')
test_1.head(3)
法一,最简单快捷
del test_1['a']
法二:
test_1 = test_1.drop('a', axis=1, inplace=True)
第一个参数是labels,即要删除的行列的名字;
axis默认为0,指删除行,删除columns时要指定axis=1;
index直接指定要删除的行,columns直接指定要删除的列;
inplace=False默认该删除操作不改变原数据,返回一个执行删除操作后的新dataframe;
inplace=True则会直接在原数据上进行删除操作,删除后无法返回。
将['PassengerId','Name','Age','Ticket']这几个列元素隐藏,只观察其他几个列元素
df.drop(['PassengerId','Name','Age','Ticket'], axis=1).head(3)
五、筛选的逻辑
以"Age"为筛选条件,显示年龄在10岁以下的乘客信息
df[df["Age"]<10].head(3)
以"Age"为条件,显示年龄在10岁到50岁之间的乘客信息,并将该数据命名为midage
midage = df[(df["Age"]>10) & (df["Age"]<50)]
midage.head(3)
显示midage的数据中第100行的"Pclass"和"Sex"的数据
midage = midage.reset_index(drop=True)
midage.head(3)
midage.loc[[100],['Pclass','Sex']]
# Pclass Sex
# 100 2 male
【拓展】reset_index()函数的作用是?
该函数用于重置数据帧的索引,即通过选取符合条件的⾏或列,原来的⾏与列序号并不是顺序的,通过此函数可以重新顺序排列。drop默认取值False,表示不删除之前的index,并将原有的索引作为一个新列;True表示删除之前的index。
使用loc方法显示midage数据第100,105,108行的"Pclass","Name"和"Sex"的数据
midage.loc[[100,105,108],['Pclass','Name','Sex']]
# Pclass Name Sex
# 100 2 Byles, Rev. Thomas Roussel Davids male
# 105 3 Cribb, Mr. John Hatfield male
# 108 3 Calic, Mr. Jovo male
使用iloc方法显示midage数据第100,105,108行的"Pclass","Name"和"Sex"的数据
midage.iloc[[100,105,108],[2,3,4]]
【拓展】对比iloc和loc的异同
二者输出的结果是相同的,但iloc的列不能用列标签,loc的列只能用列标签,不能用索引或切片。
六、了解数据
数据排序
#自己构建一个都为数字的DataFrame数据
frame = pd.DataFrame( #创建一个DataFrame对象
np.arange(8).reshape((2, 4)), #生成(2*4)二维数组,第一列:0,1,2,3 第二列:4,5,6,7
index=['2', '1'], #DataFrame对象的索引列(标注行的信息)
columns=['d', 'a', 'b', 'c']) #DataFrame对象的索引行(标注列的信息)
frame.sort_values(by='c', ascending=True) #升序排列
#by参数指向要排列的列;ascending参数指向排序的方式,True升序False降序
frame.sort_index() #让行索引升序排序
frame.sort_index(axis=1) #让列索引升序排序
frame.sort_index(axis=1, ascending=False) #让列索引降序排序
frame.sort_values(by=['a', 'c'], ascending=False) #任选两列数据同时降序排序
对泰坦尼克号数据按票价和年龄两列进行降序综合排序
text = pd.read_csv('train_chinese.csv')
text.sort_values(by=['票价', '年龄'], ascending=False).head(3)
【思考】排序后,如果仅关注年龄和票价两列,根据常识知道票价越高的客舱越好,明显看出票价前20的乘客中存活14人,这是相当高的比例,则可进一步分析票价和存活之间的关系,年龄和存活之间的关系。
数据相加
frame1_a = pd.DataFrame(np.arange(9.).reshape(3, 3),
columns=['a', 'b', 'c'],
index=['one', 'two', 'three'])
frame1_b = pd.DataFrame(np.arange(12.).reshape(4, 3),
columns=['a', 'e', 'c'],
index=['first', 'one', 'two', 'second'])
frame1_a + frame1_b #将frame_a和frame_b进行相加
#两个DataFrame相加后,会返回一个新的DataFrame,对应行和列的值会相加,没有对应的会变成空值NaN
通过泰坦尼克号数据计算出在船上最大的家族有多少人
max(text['兄弟姐妹个数'] + text['父母子女个数'])
#先让这两列相加返回一个DataFrame,然后用max函数求出最大值为10
描述性统计
使用Pandas的describe()函数查看数据基本统计信息
frame2 = pd.DataFrame([[1.4, np.nan], [7.1, -4.5], [np.nan, np.nan], [0.75, -1.3]],
index=['a', 'b', 'c', 'd'], columns=['one', 'two'])
frame2.describe() #观察frame2的数据基本信息
# one two
# count 3.000000 2.000000 样本数据大小
# mean 3.083333 -2.900000 样本数据的平均值
# std 3.493685 2.262742 样本数据的标准差
# min 0.750000 -4.500000 样本数据的最小值
# 25% 1.075000 -3.700000 样本数据的上四分位数
# 50% 1.400000 -2.900000 样本数据的中位数
# 75% 4.250000 -2.100000 样本数据的下四分位数
# max 7.100000 -1.300000 样本数据的最大值
分别看看泰坦尼克号数据集中票价、父母子女数据的基本统计数据
text['票价'].describe()
# count 891.000000 一共有891个票价数据
# mean 32.204208 平均值约为:32.20
# std 49.693429 标准差约为49.69,说明票价波动特别大
# min 0.000000 有人没有花钱乘船
# 25% 7.910400 25%的人的票价低于7.91
# 50% 14.454200 50%的人的票价低于14.45
# 75% 31.000000 75%的人的票价低于31.00
# max 512.329200 票价最大值约为512.33
# Name: 票价, dtype: float64
text['父母子女个数'].describe()
# count 891.000000
# mean 0.381594
# std 0.806057
# min 0.000000
# 25% 0.000000
# 50% 0.000000
# 75% 0.000000
# max 6.000000
# Name: 父母子女个数, dtype: float64