import pandas as pd
import numpy as np
数据预处理的四种技术:数据合并,数据清洗,数据标准化,数据转换。
一 合并数据
1 堆叠数据
横向堆叠
使用方法:
***pd.concat(objs,join=‘outer’, join_axes=None,ignore_index=False, keys=None, levels=None, names=None, verify_interity=False, copy=True)***
参数 |
说明 |
objs |
接受用于合并的series,dataframe的组合。以列表的形式 |
axis |
表示堆叠的轴向,默认axis为0,表示纵向堆叠 |
join |
接受inner或outer。表示其他轴向上的索引是按交集还是并集进行合并,默认为outer |
ignore_index |
接受boolean.表示是否不保留连接轴上的索引,产生一组新索引range(toatal_length)默认为False |
verify_intergrity |
接受boolean,检查新连接的轴是否包含重复项。如果发现重复项,则引发异常。默认为False |
data1 = pd.DataFrame(np.random.rand(3,3),index = list('abc'),columns = list('ABC'))
data1
|
A |
B |
C |
a |
0.582417 |
0.102053 |
0.021993 |
b |
0.052730 |
0.543221 |
0.174459 |
c |
0.573840 |
0.909638 |
0.048835 |
data2 = pd.DataFrame(np.random.rand(2,2),index = list('ad'),columns = list('AD'))
data2
|
A |
D |
a |
0.427735 |
0.142095 |
d |
0.121431 |
0.563111 |
pd.concat([data1,data2],axis = 1, join = 'outer',ignore_index=False)
|
A |
B |
C |
A |
D |
a |
0.582417 |
0.102053 |
0.021993 |
0.427735 |
0.142095 |
b |
0.052730 |
0.543221 |
0.174459 |
NaN |
NaN |
c |
0.573840 |
0.909638 |
0.048835 |
NaN |
NaN |
d |
NaN |
NaN |
NaN |
0.121431 |
0.563111 |
pd.concat([data1,data2],axis = 1, join = 'inner',ignore_index=False)
|
A |
B |
C |
A |
D |
a |
0.582417 |
0.102053 |
0.021993 |
0.427735 |
0.142095 |
纵向堆叠
pd.concat([data1,data2],axis = 0,join='outer',ignore_index=False)
|
A |
B |
C |
D |
a |
0.582417 |
0.102053 |
0.021993 |
NaN |
b |
0.052730 |
0.543221 |
0.174459 |
NaN |
c |
0.573840 |
0.909638 |
0.048835 |
NaN |
a |
0.427735 |
NaN |
NaN |
0.142095 |
d |
0.121431 |
NaN |
NaN |
0.563111 |
pd.concat([data1,data2], axis =0, join = 'inner',ignore_index=False)
|
A |
a |
0.582417 |
b |
0.052730 |
c |
0.573840 |
a |
0.427735 |
d |
0.121431 |
除了concat方法之外,append方法也可以实现纵向堆叠。但是前提是,带合并的两张表的列名要一致,如若不然,则会报错。
data1.append(data2,ignore_index=False)
|
A |
B |
C |
D |
a |
0.582417 |
0.102053 |
0.021993 |
NaN |
b |
0.052730 |
0.543221 |
0.174459 |
NaN |
c |
0.573840 |
0.909638 |
0.048835 |
NaN |
a |
0.427735 |
NaN |
NaN |
0.142095 |
d |
0.121431 |
NaN |
NaN |
0.563111 |
2 主键合并数据
主键合并就是通过一个或者多个键将两个数据集的行连接起来。类似于sql中的join。
merge方法
***pd.merge(left,right,how,on,left_on,right_on,left_index,right_index,sort,suffixes)***
参数 |
说明 |
left |
接受dataframe或者series。表示要添加的新数据。没有默认 |
right |
接受dataframe或者series。表示要添加的数据,没有默认 |
how |
接受inner,outer,left,right。表示数据的连接方式。默认为inner |
on |
表示两个数据合并的主键(必须一致)。默认为None |
right_on |
接受string或者sequence.表示right参数接收数据用于合并的主键。默认为None |
left_on |
接受string或者sequence.表示left参数接收数据用于合并的主键。默认为None |
left_index |
接受True or False。表示是否将left参数数据的index(行索引)作为连接主键。默认为None |
right_index |
接受True or False。表示是否将right参数数据的index(行索引)作为连接主键。默认为None |
sort |
接受boolean。表示是否根据连接键对合并后的数据进行降序。默认为False |
suffixes |
接受tupple。表示用于追加到left和right参数接受数据列明相同时的后缀。默认为(’_x’,’_y’) |
主键合并的三种情况:
1 左右数据有共同的列名,用共同的列名作为主键。此时使用on参数,传入共同的列名。合并后的数据列数为原来数据的列数和减去连接键的数量
2 使用不同列名主键进行合并
3 赋予left_index和right_index参数。使用原本数据的index(行索引)作为主键进行合并
data_1 = pd.DataFrame({'key1':list('aavde'),'key2':list('asdfs'),'key3':list(str(12345))})
data_1
|
key1 |
key2 |
key3 |
0 |
a |
a |
1 |
1 |
a |
s |
2 |
2 |
v |
d |
3 |
3 |
d |
f |
4 |
4 |
e |
s |
5 |
data_2 = pd.DataFrame({'key2':list('aiopd'),'key3':list('33333')})
data_2
|
key2 |
key3 |
0 |
a |
3 |
1 |
i |
3 |
2 |
o |
3 |
3 |
p |
3 |
4 |
d |
3 |
用共同的列名作为主键
pd.merge(data_1,data_2,on = 'key2',how = 'inner')
|
key1 |
key2 |
key3_x |
key3_y |
0 |
a |
a |
1 |
3 |
1 |
v |
d |
3 |
3 |
pd.merge(data_1,data_2,on = 'key2',how = 'outer')
|
key1 |
key2 |
key3_x |
key3_y |
0 |
a |
a |
1 |
3 |
1 |
a |
s |
2 |
NaN |
2 |
e |
s |
5 |
NaN |
3 |
v |
d |
3 |
3 |
4 |
d |
f |
4 |
NaN |
5 |
NaN |
i |
NaN |
3 |
6 |
NaN |
o |
NaN |
3 |
7 |
NaN |
p |
NaN |
3 |
pd.merge(data_1,data_2,on = 'key2',how = 'left')
|
key1 |
key2 |
key3_x |
key3_y |
0 |
a |
a |
1 |
3 |
1 |
a |
s |
2 |
NaN |
2 |
v |
d |
3 |
3 |
3 |
d |
f |
4 |
NaN |
4 |
e |
s |
5 |
NaN |
pd.merge(data_1,data_2,on = 'key2',how = 'right')
|
key1 |
key2 |
key3_x |
key3_y |
0 |
a |
a |
1 |
3 |
1 |
v |
d |
3 |
3 |
2 |
NaN |
i |
NaN |
3 |
3 |
NaN |
o |
NaN |
3 |
4 |
NaN |
p |
NaN |
3 |
因为data_1与data_2除了相同的key2列名外,还有相同的列名key3。因此合并后的数据相同的要以区分开来。此时就可以通过suffixes设置
pd.merge(data_1,data_2,on = 'key2',how = 'inner',suffixes=('_data_1','_data_2 '))
|
key1 |
key2 |
key3_data_1 |
key3_data_2 |
0 |
a |
a |
1 |
3 |
1 |
v |
d |
3 |
3 |
用不同的列名作为主键
pd.merge(data_1,data_2,how = 'inner',left_on = 'key1',right_on = 'key2')
|
key1 |
key2_x |
key3_x |
key2_y |
key3_y |
0 |
a |
a |
1 |
a |
3 |
1 |
a |
s |
2 |
a |
3 |
2 |
d |
f |
4 |
d |
3 |
用索引作为主键
data_1
|
key1 |
key2 |
key3 |
0 |
a |
a |
1 |
1 |
a |
s |
2 |
2 |
v |
d |
3 |
3 |
d |
f |
4 |
4 |
e |
s |
5 |
data_2
|
key2 |
key3 |
0 |
a |
3 |
1 |
i |
3 |
2 |
o |
3 |
3 |
p |
3 |
4 |
d |
3 |
pd.merge(data_1,data_2,how = 'inner',left_index = True,right_index=True)
|
key1 |
key2_x |
key3_x |
key2_y |
key3_y |
0 |
a |
a |
1 |
a |
3 |
1 |
a |
s |
2 |
i |
3 |
2 |
v |
d |
3 |
o |
3 |
3 |
d |
f |
4 |
p |
3 |
4 |
e |
s |
5 |
d |
3 |
![image.png]()
data_1与data_2是两个数据集的索引作为主键进行合并的。
join方法
使用join方法时,两个主键的名字必须相同。
***dataframe.join(self,other,on=None,how=‘left’,lsuffix=’’,resuffix=’’,sort=False)***
参数 |
说明 |
other |
接收dataframe或者series或者list.表示参与连接的其他dataframe |
on |
接收列名或者包含列名的List,tuple。表示用于连接的列名。默认为None |
how |
接收 inner outer left right,默认为inner |
lsuffix |
接受string,表示用于追加到左侧重叠列名的尾缀,无默认 |
rsuffix |
接受string,表示用于追加到右侧重叠列名的尾缀,无默认 |
sort |
接受boolean,根据连接键对合并后的数据进行排序 |
data_1.join(data_2,on = 'key2',lsuffix=' ',rsuffix=' ')
|
key1 |
key2 |
key3 |
key2 |
key3 |
0 |
a |
a |
1 |
NaN |
NaN |
1 |
a |
s |
2 |
NaN |
NaN |
2 |
v |
d |
3 |
NaN |
NaN |
3 |
d |
f |
4 |
NaN |
NaN |
4 |
e |
s |
5 |
NaN |
NaN |
data_1
|
key1 |
key2 |
key3 |
0 |
a |
a |
1 |
1 |
a |
s |
2 |
2 |
v |
d |
3 |
3 |
d |
f |
4 |
4 |
e |
s |
5 |
data_2
|
key2 |
key3 |
0 |
a |
3 |
1 |
i |
3 |
2 |
o |
3 |
3 |
p |
3 |
4 |
d |
3 |
3 重叠合并数据
此处的数据合并比较类似于字典中的updata方法。用一个dataframe来更新弥补另一个dataframe中相同位置处的缺失值。
***dataframe.combine_first(other)***
data_t = pd.DataFrame([[np.nan,3,5],[np.nan,4.6,np.nan],[np.nan,7,np.nan]],index = [0,1,2],columns=[0,1,2])
data_t
|
0 |
1 |
2 |
0 |
NaN |
3.0 |
5.0 |
1 |
NaN |
4.6 |
NaN |
2 |
NaN |
7.0 |
NaN |
data_e = pd.DataFrame([[42,np.nan,8.2],[10,7.0,4.0]])
data_e
|
0 |
1 |
2 |
0 |
42 |
NaN |
8.2 |
1 |
10 |
7.0 |
4.0 |
data_t.combine_first(data_e)
|
0 |
1 |
2 |
0 |
42.0 |
3.0 |
5.0 |
1 |
10.0 |
4.6 |
4.0 |
2 |
NaN |
7.0 |
NaN |
二 清洗数据
检测与处理重复值
方法:
***dataframe.drop_duplicates(subset=None,keep=‘first’,inplace=False)***
参数 |
说明 |
subset |
接受string或sequence。表示去重的列。默认为None |
keep |
表示保留第几个数据.first,last,false(表示一个不保留),默认为first |
inplace |
接受boolean,表示是否在原表上进行操作,默认为False |
data_repeat = pd.DataFrame({'key1':list('aabcdde'),'key2':[1,1,2,3,4,4,5]})
data_repeat
|
key1 |
key2 |
0 |
a |
1 |
1 |
a |
1 |
2 |
b |
2 |
3 |
c |
3 |
4 |
d |
4 |
5 |
d |
4 |
6 |
e |
5 |
data_repeat.drop_duplicates(subset='key2')
|
key1 |
key2 |
0 |
a |
1 |
2 |
b |
2 |
3 |
c |
3 |
4 |
d |
4 |
6 |
e |
5 |
data_repeat.drop_duplicates(subset=['key1','key2'])
|
key1 |
key2 |
0 |
a |
1 |
2 |
b |
2 |
3 |
c |
3 |
4 |
d |
4 |
6 |
e |
5 |
检测与处理缺失值
识别缺失值
pandas中提供isnull和notnull两种方法来检测是否存在缺失值。
isnull表示存在缺失值
notnull表示不存在缺失值
data_null = pd.DataFrame({'key1':[np.nan,1,2,3,4,5,np.nan],'key2':[1,2,3,4,5,6,np.nan]})
data_null
|
key1 |
key2 |
0 |
NaN |
1.0 |
1 |
1.0 |
2.0 |
2 |
2.0 |
3.0 |
3 |
3.0 |
4.0 |
4 |
4.0 |
5.0 |
5 |
5.0 |
6.0 |
6 |
NaN |
NaN |
data_null.isnull()
|
key1 |
key2 |
0 |
True |
False |
1 |
False |
False |
2 |
False |
False |
3 |
False |
False |
4 |
False |
False |
5 |
False |
False |
6 |
True |
True |
data_null.isnull().sum()
key1 2
key2 1
dtype: int64
处理缺失值
处理缺失值的方法主要有:删除法,替换法,插值法。
删除法
***dataframe.dropna(axis = 0,how = ‘any’,thresh=None,subset=None,inplace = None)***
参数 |
说明 |
how |
表示删除的形式,any:只有存在缺失值就删除,all:全部为缺失值才删除 |
thresh |
接受int数据,表示容忍非缺失值的数据个数 |
subset |
接受array,表示进行去重的列/行。默认为None |
inplace |
|
data_null
|
key1 |
key2 |
0 |
NaN |
1.0 |
1 |
1.0 |
2.0 |
2 |
2.0 |
3.0 |
3 |
3.0 |
4.0 |
4 |
4.0 |
5.0 |
5 |
5.0 |
6.0 |
6 |
NaN |
NaN |
data_null.dropna(axis = 0,how = 'any',subset=['key1','key2'])
|
key1 |
key2 |
1 |
1.0 |
2.0 |
2 |
2.0 |
3.0 |
3 |
3.0 |
4.0 |
4 |
4.0 |
5.0 |
5 |
5.0 |
6.0 |
data_null.dropna(axis = 0,how = 'all',subset=['key1','key2'])
|
key1 |
key2 |
0 |
NaN |
1.0 |
1 |
1.0 |
2.0 |
2 |
2.0 |
3.0 |
3 |
3.0 |
4.0 |
4 |
4.0 |
5.0 |
5 |
5.0 |
6.0 |
data_null['key3'] = [1,2,3,4,6,7,8]
data_null
|
key1 |
key2 |
key3 |
0 |
NaN |
1.0 |
1 |
1 |
1.0 |
2.0 |
2 |
2 |
2.0 |
3.0 |
3 |
3 |
3.0 |
4.0 |
4 |
4 |
4.0 |
5.0 |
6 |
5 |
5.0 |
6.0 |
7 |
6 |
NaN |
NaN |
8 |
data_null.dropna(thresh=1)
|
key1 |
key2 |
key3 |
0 |
NaN |
1.0 |
1 |
1 |
1.0 |
2.0 |
2 |
2 |
2.0 |
3.0 |
3 |
3 |
3.0 |
4.0 |
4 |
4 |
4.0 |
5.0 |
6 |
5 |
5.0 |
6.0 |
7 |
6 |
NaN |
NaN |
8 |
data_null.dropna(thresh=2)
|
key1 |
key2 |
key3 |
0 |
NaN |
1.0 |
1 |
1 |
1.0 |
2.0 |
2 |
2 |
2.0 |
3.0 |
3 |
3 |
3.0 |
4.0 |
4 |
4 |
4.0 |
5.0 |
6 |
5 |
5.0 |
6.0 |
7 |
data_null.dropna(thresh=3)
|
key1 |
key2 |
key3 |
1 |
1.0 |
2.0 |
2 |
2 |
2.0 |
3.0 |
3 |
3 |
3.0 |
4.0 |
4 |
4 |
4.0 |
5.0 |
6 |
5 |
5.0 |
6.0 |
7 |
替换法
***dataframe.fillna(value = None,method=None,axis=None,inpalce=False,limit=None)***
参数 |
说明 |
value |
接受dict,series,dataframe。表示用来替换缺失值。无默认 |
method |
接受特定string,backfill或者bfill表示使用下一个 非缺失值来填补缺失值。pad或者ffill表示使用上一个非缺失值来填补 |
data_null
|
key1 |
key2 |
key3 |
0 |
NaN |
1.0 |
1 |
1 |
1.0 |
2.0 |
2 |
2 |
2.0 |
3.0 |
3 |
3 |
3.0 |
4.0 |
4 |
4 |
4.0 |
5.0 |
6 |
5 |
5.0 |
6.0 |
7 |
6 |
NaN |
NaN |
8 |
data_null.fillna(111)
|
key1 |
key2 |
key3 |
0 |
111.0 |
1.0 |
1 |
1 |
1.0 |
2.0 |
2 |
2 |
2.0 |
3.0 |
3 |
3 |
3.0 |
4.0 |
4 |
4 |
4.0 |
5.0 |
6 |
5 |
5.0 |
6.0 |
7 |
6 |
111.0 |
111.0 |
8 |
插值法(待补充)
检测与处理异常值