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
用共同的列名作为主键
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
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
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
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')
data_repeat.drop_duplicates(subset=['key1','key2'])
检测与处理缺失值
识别缺失值
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 |
---|
插值法(待补充)
检测与处理异常值