动手学数据分析 -- Task02_1

【回顾&引言】前面一章的内容大家可以感觉到我们主要是对基础知识做一个梳理,让大家了解数据分析的一些操作,主要做了数据的各个角度的观察。那么在这里,我们主要是做数据分析的流程性学习,主要是包括了数据清洗以及数据的特征处理,数据重构以及数据可视化。这些内容是为数据分析最后的建模和模型评价做一个铺垫。

开始之前,导入numpy、pandas包和数据

#加载所需的库
import numpy as np
import pandas as pd
#加载数据train.csv
df = pd.read_csv('train.csv')
df

2 第二章:数据清洗及特征处理

我们拿到的数据通常是不干净的,所谓的不干净,就是数据中有缺失值,有一些异常点等,需要经过一定的处理才能继续做后面的分析或建模,所以拿到数据的第一步是进行数据清洗,本章我们将学习缺失值、重复值、字符串和数据转换等操作,将数据清洗成可以分析或建模的亚子。

2.1 缺失值观察与处理

我们拿到的数据经常会有很多缺失值,比如我们可以看到Cabin列存在NaN,那其他列还有没有缺失值,这些缺失值要怎么处理呢

2.1.1 任务一:缺失值观察

(1) 请查看每个特征缺失值个数
(2) 请查看Age, Cabin, Embarked列的数据
以上方式都有多种方式,所以大家多多益善

#写入代码
ageNa = df['Age'].isna().sum()
cabinNa = df['Age'].isna().sum()
embarkedNa = df['Embarked'].isna().sum()
print(ageNa, cabinNa, embarkedNa)
#写入代码
ageNa = df['Age'].isnull().sum()
cabinNa = df['Age'].isnull().sum()
embarkedNa = df['Embarked'].isnull().sum()
print(ageNa, cabinNa, embarkedNa)
#写入代码
df.info()

df[['Age','Cabin','Embarked']].head(3)

2.1.2 任务二:对缺失值进行处理

(1)处理缺失值一般有几种思路
去掉含有缺失值的样本(行)
将含有缺失值的列(特征向量)去掉
将缺失值用某些值填充(0,平均值、中值等)
(2) 请尝试对Age列的数据的缺失值进行处理

(3) 请尝试使用不同的方法直接对整张表的缺失值进行处理

处理缺失值的一般思路:

提醒:可使用的函数有--->dropna函数与fillna函数

# 去除含有缺失值的样本
df1 = df.dropna()
df1
# 对Age列的数据的缺失值进行处理
df2 = df.dropna(subset=['Age'])
df2

df[df['Age']==None]=0
df

df[df['Age'].isnull()] = 0
df

df[df['Age'] == np.nan] = 0
df.head()
#写入代码
# 将含有缺失值的列去掉
df3 = df.dropna(axis=1)
df3
#写入代码
# dropna()函数的作用是去除读入的数据中含有NaN的行
df.dropna().head(3)
# 参数
# axis:default 0指行,1为列
# how:  default any指带缺失值的所有行或列, all指只有改行或该列全为NaN的才会被删除
# thresh: int,保留含有int个非空值的行或列
# subset: 对特定的列进行缺失值的删除处理
# inplace: default False指不替换源文件, True指替换源文件
#写入代码
# fillna()函数的作用是指定一个数值来替代数据中所有的控制NaN
df.fillna(0).head(3)
# fillna(value=None, *, method=None, axis=None, inplace=False, limit=None, downcast=None)
# 参数axis、inplace与dropna一致
# method: 作用是填充。如果为ffill:则是将这个空值的前一个数据复制给这个空值,如果为bfill,则是将这个空值后的一个数据复制给这个空值
# limit: 限制填充的空值的个数,比如某一列有两个空值,如果这里设置为1,则将有一个空值不去管它

【思考1】dropna和fillna有哪些参数,分别如何使用呢?
【思考】检索空缺值用np.nan,None以及.isnull()哪个更好,这是为什么?如果其中某个方式无法找到缺失值,原因又是为什么?

思考回答

Pandas中的空值有三个:np.nan、None、pd.NaT(时间格式的空值),这三个值可以用Pandas中的函数isnull()、notnull()、isna()进行判断。

在Python解释器看来,np.nan的类型是float,None的类型是NoneType,所以如果数据列为float的数值列,若用==None去检索将检索不到,从而无法找到缺失值。

因此用isnull()更好,这个函数可以np.nan和None一起检索到。

【参考】https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.dropna.html
【参考】https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.fillna.html

2.2 重复值观察与处理

由于这样那样的原因,数据中会不会存在重复值呢,如果存在要怎样处理呢

2.2.1 任务一:请查看数据中的重复值

#写入代码
df = pd.read_csv('train.csv')
df[df.duplicated()]

2.2.2 任务二:对重复值进行处理

(1)重复值有哪些处理方式呢?
pandas提供了两个函数专门用来处理数据中的重复值,分别为duplicated()和drop_duplicates()方法
duplicated()用于标记是否有重复值
和drop_duplicates()用于删除重复值
(2)处理我们数据的重复值

方法多多益善

#重复值有哪些处理方式:
df = df.drop_duplicates()
df
#写入代码
df[df.duplicated()]
df

2.2.3 任务三:将前面清洗的数据保存为csv格式

#写入代码
df.to_csv('clear_data_self.csv')

2.3 特征观察与处理

我们对特征进行一下观察,可以把特征大概分为两大类:
数值型特征:Survived ,Pclass, Age ,SibSp, Parch, Fare,其中Survived, Pclass为离散型数值特征,Age,SibSp, Parch, Fare为连续型数值特征
文本型特征:Name, Sex, Cabin,Embarked, Ticket,其中Sex, Cabin, Embarked, Ticket为类别型文本特征,数值型特征一般可以直接用于模型的训练,但有时候为了模型的稳定性及鲁棒性会对连续变量进行离散化。文本型特征往往需要转换成数值型特征才能用于建模分析。

2.3.1 任务一:对年龄进行分箱(离散化)处理

(1) 分箱操作是什么?

(2) 将连续变量Age平均分箱成5个年龄段,并分别用类别变量12345表示

(3) 将连续变量Age划分为[0,5) [5,15) [15,30) [30,50) [50,80)五个年龄段,并分别用类别变量12345表示

(4) 将连续变量Age按10% 30% 50% 70% 90%五个年龄段,并用分类变量12345表示

(5) 将上面的获得的数据分别进行保存,保存为csv格式

#分箱操作是什么:
# 分箱是一种常见的数据预处理技术,有时也被成为分桶或离散化,他可用于将连续数据的间隔分组到“箱”或“桶”中。
df = pd.read_csv("train.csv")
df[df['Age'].isnull()] = 0
# 将连续变量Age平均分箱成5个年龄段,并分别用类别变量12345表示
df['AgeBand'] = pd.cut(df['Age'], 5, labels = [1,2,3,4,5])
df
#写入代码
# 将连续变量Age划分为[0,5) [5,15) [15,30) [30,50) [50,80)五个年龄段,并分别用类别变量12345表示
df.loc[df['Age'].between(0, 5, 'left'), 'AgeBand'] = 1
df.loc[df['Age'].between(5, 15, 'left'), 'AgeBand'] = 2
df.loc[df['Age'].between(15, 30, 'left'), 'AgeBand'] = 3
df.loc[df['Age'].between(30, 50, 'left'), 'AgeBand'] = 4
df.loc[df['Age'].between(50, 80, 'left'), 'AgeBand'] = 5
df

df['AgeBand'] = pd.cut(df['Age'],[0,5,15,30,50,80],labels = [1,2,3,4,5])
df
#写入代码
# 将连续变量Age按10% 30% 50% 70% 90%五个年龄段,并用分类变量12345表示
df = pd.read_csv("train.csv")
df['AgeBand'] = pd.qcut(df['Age'],[0,0.1,0.3,0.5,0.7,0.9],labels = [1,2,3,4,5])
df.head()
#写入代码
df.to_csv('test_pr.csv')

【参考】https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.cut.html
【参考】https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.qcut.html

2.3.2 任务二:对文本变量进行转换

(1) 查看文本变量名及种类
(2) 将文本变量Sex, Cabin ,Embarked用数值变量12345表示
(3) 将文本变量Sex, Cabin, Embarked用one-hot编码表示

#写入代码
# 查看你文本变量名及种类
# 方法一
df['Sex'].value_counts()
# 方法二
df['Sex'].unique()
# 方法三
df['Sex'].nunique()
#写入代码
# 将文本变量Sex, Cabin ,Embarked用数值变量12345表示
#方法一: replace
df['Sex_num'] = df['Sex'].replace(['male','female'],[1,2])

#方法二: map
df['Sex_num'] = df['Sex'].map({'male': 1, 'female': 2})

#方法三: 使用sklearn.preprocessing的LabelEncoder
from sklearn.preprocessing import LabelEncoder
for feat in ['Cabin', 'Ticket']:
    lbl = LabelEncoder()
    label_dict = dict(zip(df[feat].unique(), range(df[feat].nunique())))
    df[feat + "_labelEncode"] = df[feat].map(label_dict)
    df[feat + "_labelEncode"] = lbl.fit_transform(df[feat].astype(str))

df.head()
#写入代码
# 将文本变量Sex, Cabin, Embarked用one-hot编码表示
for feat in ["Age", "Embarked"]:
#     x = pd.get_dummies(df["Age"] // 6)
#     x = pd.get_dummies(pd.cut(df['Age'],5))
    x = pd.get_dummies(df[feat], prefix=feat)
    df = pd.concat([df, x], axis=1)
    #df[feat] = pd.get_dummies(df[feat], prefix=feat)

df.head()

2.3.3 任务三:从纯文本Name特征里提取出Titles的特征(所谓的Titles就是Mr,Miss,Mrs等)

#写入代码
df['Title'] = df.Name.str.extract('([A-Za-z]+)\.', expand=False)
df.head()
#保存最终你完成的已经清理好的数据
df.to_csv('test_fin.csv')
posted @ 2023-01-20 00:05  HoroSherry  阅读(29)  评论(0编辑  收藏  举报