动手学数据分析—数据清洗及特征处理
全部参考 datawhale-动手学数据分析
导入numpy、pandas包和数据
import numpy as np
import pandas as pd
print(pd.__version__) # 1.0.3
载入数据
df=pd.read_csv('train.csv')
df.head()
1. 数据清洗及特征处理
1.1 缺失值观察与处理
缺失值的处理方法
函数名 | 描述 |
---|---|
dropna | 根据每个标签的值是否缺失数据来筛选轴标签,并根据允许丢失的数据来确定阈值 |
fillna | 用某些值填充缺失的数据或使用插值的方法(‘ffill’,‘bfill’) |
isnull | 返回表明那些是确实值的布尔值 |
notnull | isnull的反函数### |
观察缺失值
# df.info() # info函数查看缺失信息
df.isna().sum()
# 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
Age列和Cabin列有缺失值
过滤缺失值
df.dropna().head() # 假设你只想保留包含一定数量的观察值的行。你 可以用thresh参数来表示
df.dropna(thresh=2).head()
补全缺失值
df.fillna(0).head()
df.fillna(method='ffill').head()
df['Age'].fillna(df['Age'].mean()).head() # 平均值填充 缺失值:
【思考1】dropna和fillna有哪些参数,分别如何使用呢?
原文链接:https://blog.csdn.net/dss_dssssd/article/details/82814673
- DataFrame.dropna(axis=0, how=‘any’, thresh=None, subset=None, inplace=False)
- DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)
【思考2】检索空缺值用np.nan要比用None好,这是为什么? - np.nan,none,Nat三种缺失值都会被替换为统一的NA符号,且不改变数据类型.
- np.nan是一个float类型的数据 None是一个NoneType类型
- 在ndarray中None显示为None 并且对象为object类型,如果进行计算 结果会报错
在用pandas和numpy处理数据阶段将None,NaN统一处理成NaN,以便支持更多的函数。
如果要判断Series,numpy.array整体的等值性,用专门的Series.equals,numpy.array函数去处理,不要自己用==判断 * 如果要将数据导入数据库,将NaN替换成None
原文连接:https://www.cnblogs.com/onemorepoint/p/8966791.html
1.2 重复值观察与处理
查看重复值:
DataFrame的duplicated方法返回的是一个布尔值Series,默认保留第一个观测到的值。传入参数keep='last’将会返回最后一个
df.duplicated().head() # 查看是否有行重复
df.duplicated(['Name']).head() # 查看Name列是否有重复值
# 0 False
# 1 False
# 2 False
# 3 False
# 4 False
# dtype: bool
删除重复值:
- drop_duplicates返回的是DataFrame,内容是 duplicated返回数组中为False的部分
df.drop_duplicates().head() # 删除重复行默认保留第一个观测到的值。
df.drop_duplicates(['Name']).head() # 删除名字相同的行
2 特征观察与处理
我们对特征进行一下观察,可以把特征大概分为两大类:
数值型特征:Survived ,Pclass, Age ,SibSp, Parch, Fare,其中Survived, Pclass为离散型数值特征,Age,SibSp, Parch, Fare为连续型数值特征
文本型特征:Name, Sex, Cabin,Embarked, Ticket,其中Sex, Cabin, Embarked, Ticket为类别型文本特征,数值型特征一般可以直接用于模型的训练,但有时候为了模型的稳定性及鲁棒性会对连续变量进行离散化。文本型特征往往需要转换成数值型特征才能用于建模分析。
2.1 分箱操作是什么?
https://www.jianshu.com/p/0805f185ecdf
一般在建立分类模型时,需要对连续变量离散化,特征离散化后,模型会更稳定,降低了模型过拟合的风险。将多个连续值分组为较少数量的“分箱”的方法
将连续变量Age平均分箱成5个年龄段,并分别用类别变量12345表示:
cats = pd.cut(df['Age'],5,labels=list('12345'))
pd.value_counts(cats).sort_index()
# 1 100
# 2 346
# 3 188
# 4 69
# 5 11
# Name: Age, dtype: int64
将连续变量Age划分为[0,5) [5,15) [15,30) [30,50) [50,80)五个年龄段,并分别用类别变量12345表示
bins = [0,5,15,30,50,80]
cats = pd.cut(df['Age'],bins,labels=list('12345'))
pd.value_counts(cats).sort_index()
# 1 44
# 2 39
# 3 326
# 4 241
# 5 64
# Name: Age, dtype: int64
将连续变量Age按10% 30% 50 70% 90%五个年龄段,并用分类变量12345表示:
bins = [0,0.1,0.3,0.5,0.7,0.9]
cats = pd.qcut(df['Age'],bins,labels=list('12345'))
pd.value_counts(cats).sort_index()
# 1 77
# 2 154
# 3 131
# 4 157
# 5 131
# Name: Age, dtype: int64
2.2 对文本变量进行转换
查看文本变量名及种类:
df['Sex'].value_counts()
# male 577
# female 314
# Name: Sex, dtype: int64
将文本变量Sex, Cabin ,Embarked用数值变量12345表示:
df['Sex'].map({'male':1,'female':2}).value_counts()
# 1 577
# 2 314
# Name: Sex, dtype: int64
df['Cabin'].value_counts()
# B96 B98 4
# G6 4
# C23 C25 C27 4
# C22 C26 3
# F2 3
# ..
# D46 1
# T 1
# A32 1
# B102 1
# B50 1
# Name: Cabin, Length: 147, dtype: int64
方法一:
arr = df['Cabin'].unique()
arr1 = range(1,len(arr)+1)
df['Cabin'].replace(arr ,arr1).value_counts()
方法二:
from sklearn.preprocessing import LabelEncoder
for feat in ['Cabin', 'Embarked']:
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()
df['Cabin_labelEncode'].value_counts()
# 147 687 # Cabin 687 缺失值
# 145 4
# 47 4
# 63 4
# 141 3
# ...
# 93 1
# 95 1
# 97 1
# 99 1
# 0 1
# Name: Cabin_labelEncode, Length: 148, dtype: int64
df['Embarked_labelEncode'].value_counts()
# 2 644
# 0 168
# 1 77
# 3 2 # Embarked 2 缺失值
# Name: Embarked_labelEncode, dtype: int64
将文本变量Sex, Cabin, Embarked用one-hot编码表示:
#方法一: OneHotEncoder
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()
3 从纯文本Name特征里提取出Titles的特征(所谓的Titles就是Mr,Miss,Mrs等)
df['Title'] = df.Name.str.extract('([A-Za-z]+)\.', expand=False)
df[['Name','Title']]