数据清洗
1 缺失值
1.1 查看缺失值
df = pd.read_csv('train.csv')
df
#法一:
df.info() #查看缺失值个数
#法二:
df.isnull().sum() #查看缺失值个数
df.isnull() #查看具体哪些值缺失
#法三:
df[df['Age'] ==np.nan]
1.2 处理缺失值
1.2.1删除含有缺失值的列或行
df.dropna()
1.2.2 补入缺失值
#法一:
df.fillna({'Age':0})#本身没有变,变得是副本
df.fillna(0) #df中所有缺失值全部补0
df.fillna(method = 'ffill')#向后填充,用前一个数补缺失值
#法二:
df.loc[df['Age].isnull(),'Age']=0 #Age列中缺失值补0
2 重复数据
2.1 显示重复数据
df[df.duplicated()] #显示重复数据
#df.duplicated() 返回布尔型数据,显示位置
2.2 删除重复行
df.drop_duplicates()
3 特征观察及处理
数值型特征:
1)离散型数值特征:存活人数、仓号
2)连续性数值特征:年龄、票价
文本型特征:姓名、性别
数值型特征一般可以直接用于模型的训练,但有时候为了模型的稳定性及鲁棒性会对连续变量进行离散化。文本型特征往往需要转换成数值型特征才能用于建模分析
3.1 离散化处理(分箱处理)
分箱处理:将连续变量分成若干段,每段看成一个分类。如果不分箱相当于用一个大函数拟合所有数据,方差会很大,拟合效果不好。
3.1.1 cut按照变量的值进行划分。
pd.cut(x, # 数据必须一维的,连续的
bins, #整数(表示分为几段)或列表(表示区间边界)
right=True, #默认左开右闭
labels=None, #各个区间的标签
retbins=False,
precision =3,
include_lowest=False)
#数据分为5段
pd.cut(df['Age'],5,labels =list('12345'))
#数据为区间
pd.cut(df['Age'],[0,5,15,30,50,80],right =False,labels =list('12345'))
3.1.2 qcut按照数据本身的数量划分,计算样本分位数
pd.qcut((x, #一维数据
q, #整数或分位数组成的数组,尽量保持每个区间的样本数量相同
labels=None,
retbins=False,
precision=3,
duplicates=’raise’) # 边界值并不是唯一的,有重复数据用duplicates='drop'
#按照百分比分段,不以0开始1结束的,只会对部分数据进行分箱。
pd.qcut(df['Age'],[0,0.1,0.3,0.5,0.7,0.9],duplicates = 'drop',labels =list('12345'))
4 对文本变量进行转换
4.1 查看文本变量及种类
df['Sex'].unique() #性别
df['Cabin'].unique()#仓号
4.2 文本变量转为数值变量
法一:replace函数作用于副本
# inplace=True直接作用于函数本身
df['Sex'].replace(['male','female'],[1,2],inplace = True)
法二:map函数
df['Sex_num'] = df['Sex'].map({'male': 1, 'female': 2})
df
法三:直接文本变量转为数值变量
from sklearn.preprocessing import LabelEncoder
df['Cabin'] = LabelEncoder().fit_transform(df['Cabin'].astype(str))
df
#将类别文本转为one-hot编码
pd.get_dummies(df['Age'],prefix = 'Age')#prefix = 'Age'表示编码后的前缀名为Age
4.3 文本中提取特征
#用到Series的字符串提取函数
df.Name.str.extract('([A-Za-z]+)\.')
数据重构
1 数据合并
1 横向合并
#法一:
result_up = pd.concat([left_up,right_up],axis=1)
#法二:
up = left_up.join(right_up)
#法三:行索引拼接,默认用两个dataframe共有的列连接
pd.merge(left_up,right_up,left_index=True,right_index =True)
2 纵向合并
#法一:
result = pd.concat([result_up,result_down])
#法二:
result = up.append(down)
2 数据聚合与运算
stack 将数据的列旋转为行 unstack 将数据的行旋转为列
result.stack()
2.1 数值分组:groupby和agg
groupby用于数据的聚合和分类计算,核心是拆分-应用-合并。
agg函数可以使用多个方法,agg函数返回的是dataframe数据类型,df.groupby('Sex')['Age'].sum()返回的是索引。
#按照性别分组的描述性信息
df.groupby('Sex').describe()
#按照性别分组得到年龄的信息
df.groupby('Sex')['Age'].describe()
#男女性的平均票价
df.groupby('Sex')['Fare'].mean()
男女的存活人数和平均票价
法一:
df.groupby('Sex')['Survived'].sum()
df.groupby('Sex')['Fare'].mean()
法二:
df.groupby('Sex').agg({'Survived':'sum','Fare':'mean'}).rename(columns = {'Survived':'Survived_sum','Fare':'Fare_mean'})
#goupby用来聚合,agg用来使用多个方法
2.2 字符串分组:正则表达式
(?P<name>) 分组起名
(?P=name) 引用别名为name 分组匹配到的字符串
\num 引用分组的num匹配到的字符串
2.2.1 数字分组
In [1]: html = '<html><h1>title</h1></html>'
In [2]: re.search(r'<(\w+)><(\w+)>.*</\2></\1>',html).group() # 2表示引用分组的第2个,即h1;1表示引用分组的第1个,即html
Out[3]: '<html><h1>title</h1></html>'
2.2.2 自定义分组
In [16]: re.search(r'<(?P<wangye>\w+)><(?P<biaoti>\w+)>(?P<neirong>.*)</(?P=biaoti)></(?P=wangye)>',html).group('wangye')
Out[16]: 'html'
In [17]: re.search(r'<(?P<wangye>\w+)><(?P<biaoti>\w+)>(?P<neirong>.*)</(?P=biaoti)></(?P=wangye)>',html).group('biaoti')
Out[17]: 'h1'
In [18]: re.search(r'<(?P<wangye>\w+)><(?P<biaoti>\w+)>(?P<neirong>.*)</(?P=biaoti)></(?P=wangye)>',html).group('neirong')
Out[18]: 'title'
数据可视化
1 柱状图
#男女存活人数
sex= df.groupby('Sex')['Survived'].sum()
sex.plot.bar()
1.1 数量叠加
sex_survived.plot(kind='bar',stacked ='True')
2 折线图
fare.plot()
3 密度曲线图
df.Age[df.Survived == 0].hist(bins=5,alpha = 0.5,density=1) #死亡人数的年龄
df.Age[df.Survived == 1].hist(bins=5,alpha = 0.5,density=1)
df.Age[df.Survived == 0].plot.density()
df.Age[df.Survived == 1].plot.density() #密度曲线
plt.legend((0,1)) #图例
plt.xlabel('Age')
plt.ylabel('density')
import seaborn as sns
for i in unique_pclass:
sns.kdeplot(df.Age[df.Pclass ==i],shade =True,linewidth=0)