python数据预处理

PYTHON 最流行库:Numpy、Matplotlib 和 Pandas。Numpy 是满足所有数学运算所需要的库,由于代码是基于数学公式运行的,因此就会使用到它。Maplotlib(具体而言,Matplotlib.pyplot)则是满足绘图所需要的库。Pandas 则是最好的导入并处理数据集的一个库。对于数据预处理而言,Pandas 和 Numpy 基本是必需的。

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

创建保存自变量的矩阵

X = dataset.iloc[:, :-1].values

第一个冒号表示提取数据集的全部行,「:-1」则表示提取除最后一列以外的所有列。最后的「.values」表示希望提取所有的值;

创建保存因变量的向量,取数据的最后一列

y = dataset.iloc[:, 3].values

一、数据描述

1.1 info()函数

info()函数用于打印DataFrame的简要摘要,显示有关DataFrame的信息,包括索引的数据类型dtype和列的数据类型dtype,非空值的数量和内存使用情况。

#(1)定义一个Dataframe
int_values = [1, 2, 3, 4, 5]
text_values = ['alpha', 'beta', 'gamma', 'delta', 'epsilon']
float_values = [0.0, 0.25, 0.5, 0.75, 1.0]
df = pd.DataFrame({"int_col": int_values, "text_col": text_values,
                  "float_col": float_values})
df

'''
int_col text_col  float_col
0        1    alpha       0.00
1        2     beta       0.25
2        3    gamma       0.50
3        4    delta       0.75
4        5  epsilon       1.00

'''
df.info(verbose=True)
'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 3 columns):
int_col      5 non-null int64
text_col     5 non-null object
float_col    5 non-null float64
dtypes: float64(1), int64(1), object(1)
memory usage: 248.0+ bytes
'''

1.2 describe()函数

describe()函数用于生成描述性统计信息。 描述性统计数据:数值类型的包括均值,标准差,最大值,最小值,分位数等;类别的包括个数,类别的数目,最高数量的类别及出现次数等;输出将根据提供的内容而有所不同。

df.describe()
'''
		float_col	int_col
count	5.000000	5.000000
mean	0.500000	3.000000
std		0.395285	1.581139
min		0.000000	1.000000
25%		0.250000	2.000000
50%		0.500000	3.000000
75%		0.750000	4.000000
max		1.000000	5.000000
'''

二、缺失值处理

类型描述
缺失值类型1) na.nan ,float类型 ,它不等于任何值,连自己都不相等。如果用nan和任何其它值比较都会返回nan,因为nan在Numpy中的类型是浮点,因此整型列会转为浮点;而字符型由于无法转化为浮点型,只能归并为object类型(‘O’),原来是浮点型的则类型不变。
2)none,与自己相等。None == None>> True
3)pd.NA 不改变原有数据类型,它代表空整数、空布尔值、空字符
缺失值判断1)isnull() ; 2)isna() ; 3)notna();
缺失值统计1)列缺失:isnull().sum(axis=0) ;2)行缺失:isnull().sum(axis=1);3)缺失率:isnull().mean();
缺失值筛选1)行筛选:df.loc[df.isnull().any(1)];2)列筛选:df.loc[:,df.isnull().any()]
缺失值填充1)全部填充:fillna();2)向前填充:ffill();3)向后填充:dfill();4)填充平均值:df.D.fillna(df.D.mean())
缺失值删除1)全部删除:df.dropna();2)行删除:df.dropna(axis = 0);3)列删除:df.dropna(axis = 1);按缺失率删除:df.loc[:,df.isnull().mean(axis=0)<0.1]
缺失值参与计算1)加法:加法会忽略缺失值;2)累加:cumsum累加会忽略NA,但值会保留在列中,可以使用skipna=False跳过有缺失值的计算并返回缺失值。;3)计数:缺失值不进入计数范围里;4)聚合分组

pandas使用浮点值NaN(Not a Number)表示浮点数和非浮点数组中的缺失值,同时python内置None值也会被当作是缺失值。

方法说明
dropna根据各标签的值中是否存在缺失值对轴标签进行过滤,可通过阈值调节对缺失值的容忍度
fillna用指定值或插值方法(如ffill或bfill)填充缺失数据
isnull返回一个含有布尔值的对象,这些布尔值表示哪些值是缺失值/NA,该对象的类型与源类型一样
notnullisnull的否定式

isna/isnull/info()

判断是不是缺失值:

df = pd.DataFrame([[np.nan, 2, np.nan, 0],
                   [3, 4, np.nan, 1],
                   [np.nan, np.nan, np.nan, 5],
                   [np.nan, 3, np.nan, 4]],
                  columns=list('ABCD'))

print(df)
'''
     A    B   C  D
0  NaN  2.0 NaN  0
1  3.0  4.0 NaN  1
2  NaN  NaN NaN  5
3  NaN  3.0 NaN  4
'''
df.isna()    ##df.isnull()
'''
A	B	C	D
0	True	False	True	False
1	False	False	True	False
2	True	True	True	False
3	True	False	True	False
'''
df.isna().sum()    ##df.isnull().sum()   df.isnull().mean()  缺失率
'''
A    3
B    0
C    4
D    0
dtype: int64
'''
df.info()
'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 4 columns):
A    1 non-null float64
B    4 non-null object
C    0 non-null float64
D    4 non-null int64
dtypes: float64(2), int64(1), object(1)
memory usage: 208.0+ bytes
'''
#可以看到一共有4行,但是有两列的非空值都不到4行

dropna

DataFrame.dropna(axis=0, how=‘any’, thresh=None, subset=None, inplace=False)
函数作用:删除含有空值的行或列

  • axis:维度,axis=0表示index行,axis=1表示columns列,默认为0
  • how:"all"表示这一行或列中的元素全部缺失(为nan)才删除这一行或列,"any"表示这一行或列中只要有元素缺失,就删除这一行或列
  • thresh:一行或一列中至少出现了thresh个才删除。
  • subset:在某些列的子集中选择出现了缺失值的列删除,不在子集中的含有缺失值得列或行不会删除(有axis决定是行还是列)
  • inplace:刷选过缺失值得新数据是存为副本还是直接在原数据上进行修改。
df = pd.DataFrame({"name": ['Alfred', 'Batman', 'Catwoman'],
                   "toy": [np.nan, 'Batmobile', 'Bullwhip'],
                   "born": [pd.NaT, pd.Timestamp("1940-04-25"), pd.NaT]})

# print(df)
'''
       name        toy       born
0    Alfred        NaN        NaT
1    Batman  Batmobile 1940-04-25
2  Catwoman   Bullwhip        NaT
'''

print(df.dropna())
'''
     name        toy       born
1  Batman  Batmobile 1940-04-25
'''

print(df)
'''
       name        toy       born
0    Alfred        NaN        NaT
1    Batman  Batmobile 1940-04-25
2  Catwoman   Bullwhip        NaT
'''

#delete colums
print(df.dropna(axis=1) )#delete co
'''
       name
0    Alfred
1    Batman
2  Catwoman
'''

#"所有值全为缺失值才删除"
print(df.dropna(how='all'))
'''
       name        toy       born
0    Alfred        NaN        NaT
1    Batman  Batmobile 1940-04-25
2  Catwoman   Bullwhip        NaT
'''

#"至少出现过两个缺失值才删除"
print(df.dropna(thresh=2))
'''
       name        toy       born
1    Batman  Batmobile 1940-04-25
2  Catwoman   Bullwhip        NaT
'''

#"删除这个subset中的含有缺失值的行或列"
print (df.dropna(subset=['name', 'born']))
'''
     name        toy       born
1  Batman  Batmobile 1940-04-25
'''

fillna

DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)
函数作用:填充缺失值

  • value:需要用什么值去填充缺失值
  • axis:确定填充维度,从行开始或是从列开始
  • method:ffill:用缺失值前面的一个值代替缺失值,如果axis =1,那么就是横向的前面的值替换后面的缺失值,如果axis=0,那么则是上面的值替换下面的缺失值。backfill/bfill,缺失值后面的一个值代替前面的缺失值。注意这个参数不能与value同时出现
  • limit:确定填充的个数,如果limit=2,则只填充两个缺失值。

df = pd.DataFrame([[np.nan, 2, np.nan, 0],
                   [3, 4, np.nan, 1],
                   [np.nan, np.nan, np.nan, 5],
                   [np.nan, 3, np.nan, 4]],
                  columns=list('ABCD'))

print(df)
'''
     A    B   C  D
0  NaN  2.0 NaN  0
1  3.0  4.0 NaN  1
2  NaN  NaN NaN  5
3  NaN  3.0 NaN  4
'''

#"横向用缺失值前面的值替换缺失值"
print(df.fillna(axis=1, method='ffill'))
'''
     A    B    C    D
0  NaN  2.0  2.0  0.0
1  3.0  4.0  4.0  1.0
2  NaN  NaN  NaN  5.0
3  NaN  3.0  3.0  4.0
'''


#"纵向用缺失值上面的值替换缺失值"
print(df.fillna(axis=0,method='ffill'))
'''
     A    B   C  D
0  NaN  2.0 NaN  0
1  3.0  4.0 NaN  1
2  3.0  4.0 NaN  5
3  3.0  3.0 NaN  4
'''

print(df.fillna(0))
##df['A'] = df['A'].fillna(111)  针对某一列替换缺失值;
##df['A'] = df['A'].fillna(df['A'].mean())  使用均值替换缺失值
##df['A'] = df['A'].fillna(df['A'].interpolate()) 使用插值函数来填写数字的缺失值,默认为‘linear’使用插值方法。
'''
     A    B    C  D
0  0.0  2.0  0.0  0
1  3.0  4.0  0.0  1
2  0.0  0.0  0.0  5
3  0.0  3.0  0.0  4
'''

#不同的列用不同的值填充:
values={'A':0,'B':1,'C':2,'D':3}
print(df.fillna(value=values))
'''
     A    B    C  D
0  0.0  2.0  2.0  0
1  3.0  4.0  2.0  1
2  0.0  1.0  2.0  5
3  0.0  3.0  2.0  4
'''
#对每列出现的替换值有次数限制,此处限制为一次
values={'A':0,'B':1,'C':2,'D':3}
print(df.fillna(value=values,limit=1))
'''
     A    B    C  D
0  0.0  2.0  2.0  0
1  3.0  4.0  NaN  1
2  NaN  1.0  NaN  5
3  NaN  3.0  NaN  4
'''

SimpleImputer

参数详解

class sklearn.impute.SimpleImputer(*, missing_values=nan, strategy=‘mean’, fill_value=None, verbose=0, copy=True, add_indicator=False)

  • missing_values:int, float, str, (默认)np.nan或是None, 即缺失值是什么。
  • strategy:空值填充的策略,共四种选择mean(默认,均值)、median(中位数)、most_frequent(众数)、constant(自定义的值,通过fill_value来定义)。
  • fill_value:str或数值,默认为Zone。当strategy =="constant"时,fill_value被用来替换所有出现的缺失值(missing_values)。fill_value为Zone,当处理的是数值数据时,缺失值(missing_values)会替换为0,对于字符串或对象数据类型则替换为"missing_value"这一字符串。
  • verbose:int,(默认)0,控制imputer的冗长。
  • copy:boolean,(默认)True,表示对数据的副本进行处理,False对数据原地修改。
  • add_indicator:boolean,(默认)False,True则会在数据后面加入n列由0和1构成的同样大小的数据,0表示所在位置非缺失值,1表示所在位置为缺失值。

常用方法

fit(X)

返回值为SimpleImputer()类,通过fit(X)方法可以计算X矩阵的相关值的大小,以便填充其他缺失数据矩阵时进行使用。

transform(X)

填补缺失值,一般使用该方法前要先用fit()方法对矩阵进行处理。

from sklearn.impute import SimpleImputer
import numpy as np
X = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
X1 = np.array([[1, 2, np.nan],
               [4, np.nan, 6],
               [np.nan, 8, 9]])
imp = SimpleImputer(missing_values=np.nan, strategy='mean')
imp.fit(X)
print(imp.transform(X1))
'''
# 运行结果
[[1. 2. 6.]
 [4. 5. 6.]
 [4. 8. 9.]]
 '''

由于fit(X)和strategy=‘mean’,所以填补值为X矩阵各列的均值。

fit_transform(X)

相当于fit() + transform(),一般使用的较多。

X1 = np.array([[1, 2, np.nan],
               [4, np.nan, 6],
               [np.nan, 8, 9]])
imp = SimpleImputer(missing_values=np.nan, strategy='mean')
print(imp.fit_transform(X1))
'''
# 运行结果
[[1.  2.  7.5]
 [4.  5.  6. ]
 [2.5 8.  9. ]]
'''
自定义填补值
X = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])

imp = SimpleImputer(missing_values=1, strategy='constant', fill_value=666)
print(imp.fit_transform(X))
'''
# 运行结果
[[666 2 3]
 [4 5 6]
 [7 8 9]]
'''

interpolate

interpolate可以用在DataFrame对象上,也可以用在Series对象上。

pandas.DataFrame.interpolate()?
DataFrame.interpolate(method=‘linear’, axis=0, limit=None, inplace=False, limit_direction=None, limit_area=None, downcast=None, **kwargs)

  • method : str,默认为‘linear’使用插值方法。 可用的插值方法:
    ‘linear’:忽略索引,线性等距插值。这是MultiIndexes支持的唯一方法。
    ‘time’:在以天或者更高频率的数据上插入给定的时间间隔长度数据。
    ‘index’, ‘values’: 使用索引的实际数值。
    ‘pad’:使用现有值填写NaN。 ‘nearest’, ‘zero’, ‘slinear’, ‘quadratic’, ‘cubic’,
    ‘spline’, ‘barycentric’, ‘polynomial’: 传递给
    scipy.interpolate.interp1d。这些方法使用索引的数值。‘polynomial’ 和 ‘spline’
    都要求您还指定一个顺序(int),例如 ,df.interpolate(method=‘polynomial’, order=5)
    ‘krogh’,‘piecewise_polynomial’,‘spline’,‘pchip’,‘akima’:包括类似名称的SciPy插值方法。
    ‘from_derivatives’:指
    scipy.interpolate.BPoly.from_derivatives,它替换了scipy
    0.18中的’piecewise_polynomial’插值方法。
  • axis : {0或’index’,1或’columns’,None},默认为None;沿轴进行interpolate。
  • limit: int;要填充的连续NaN的最大数量。必须大于0。
  • inplace : bool,默认为False;如果可以,更新现有数据。
  • limit_direction :
    {‘forward’,‘backward’,‘both’},默认为’forward’;如果指定了限制,则将沿该方向填充连续的NaN。
  • limit_area : {None, ‘inside’, ‘outside’},
    默认为None;如果指定了限制,则连续的NaN将填充此限制。 None:无填充限制。 ‘inside’:仅填充有效值包围的NaN。
    ‘outside’: 仅在有效值之外填充NaN。
import pandas as pd
import numpy as np

data = pd.Series([1,2,3,np.nan,np.nan,6,np.nan])
data
'''
0    1.0
1    2.0
2    3.0
3    NaN
4    NaN
5    6.0
6    NaN
dtype: float64
'''
data.interpolate()    ## 不设置任何参数
'''
0    1.0
1    2.0
2    3.0
3    4.0
4    5.0
5    6.0
6    6.0
dtype: float64
'''
data.interpolate(method='pad', limit=1)     ####使用‘pad’方法,limit设置为1
'''
0    1.0
1    2.0
2    3.0
3    3.0
4    NaN
5    6.0
6    6.0
dtype: float64
'''

df = pd.DataFrame([(0.0, np.nan, -1.0, 1.0),
                   (np.nan, 2.0, np.nan, np.nan),
                   (2.0, 3.0, np.nan, 9.0),
                   (np.nan, 4.0, -4.0, 16.0)],
                   columns=list('abcd'))
print(df)            
'''
    a    b    c     d
0  0.0  NaN -1.0   1.0
1  NaN  2.0  NaN   NaN
2  2.0  3.0  NaN   9.0
3  NaN  4.0 -4.0  16.0
'''
df.interpolate(method='linear', limit_direction='backward', axis=0)
'''
	a 	b  	c	   d
0	0.0	2.0	-1.0	1.0
1	1.0	2.0	-2.0	5.0
2	2.0	3.0	-3.0	9.0
3	NaN	4.0	-4.0	16.0
'''
#最后一行中的值无法填充,因为值的填充方向为backward并且没有可用于插值的后续值。

替换空值

需要把含有空值的那一列提出来单独处理,然后在放进去就好。

df = pd.DataFrame([[np.nan, 2, np.nan, 0],
                   [3, 4, "", 1],
                   [np.nan, np.nan, np.nan, 5],
                   [np.nan, 3, "", 4]],
                  columns=list('ABCD'))

print(df)
'''
     A    B    C  D
0  NaN  2.0  NaN  0
1  3.0  4.0       1
2  NaN  NaN  NaN  5
3  NaN  3.0       4
'''
clean_z = df['C'].fillna(0)
clean_z[clean_z==''] = 'hello'
df['C'] = clean_z
print(df)
'''
     A    B      C  D
0  NaN  2.0      0  0
1  3.0  4.0  hello  1
2  NaN  NaN      0  5
3  NaN  3.0  hello  4
'''

三、重复值处理

duplicated()方法判断是否有重复值

DataFrame.duplicated(subset=None, keep=‘first’)

  • subset 表示识别重复项的列索引或列索引序列。默认标识所有的列索引
  • keep 表示采用哪种方式保留重复项。
    1)‘first’,默认值,删除重复项,仅保留第一次出现的数据项。
    2)‘last’,删除重复项,仅保留最后一次出现的数据项。
    3)‘False’,表示将所有相同的数据都标记为重复项。
import pandas as pd
import numpy as np 
stu_info=pd.DataFrame({'序号':['S1','S2','S1','S4','S4'],
                '姓名':['张三','李四','张三','赵六','赵六'],
                '性别':['女','男','女','男','男'],
                '年龄':[15,16,15,14,14],
                '住址':['苏州','南京','苏州',np.nan,np.nan]})
stu_info
'''
	住址	姓名	年龄	序号	性别
0	苏州	张三	15	S1	女
1	南京	李四	16	S2	男
2	苏州	张三	15	S1	女
3	NaN	赵六	14	S4	男
4	NaN	赵六	14	S4	男
'''
# 检测stu_info对象中的重复值
stu_info.duplicated()
'''
0    False
1    False
2     True
3    False
4     True
dtype: bool
'''
# 筛选stu_info中重复值标记为True的数据记录
stu_info[stu_info.duplicated()]
'''
	住址	姓名	年龄	序号	性别
2	苏州	张三	15		S1		女
4	NaN		赵六	14		S4		男
'''

duplicates方法删除重复行

DataFrame.drop_duplicates(subset=None, keep=‘first’, inplace=False, ignore_index=False)

  • subset 表示删除重复项的列索引或列索引序列,默认删除所有的列索引。
  • keep 表示采用哪种方式保留重复项。 ‘first’,默认值,删除重复项,仅保留第一次出现的数据项。‘last’,删除重复项,仅保留最后一次出现的数据项。‘False’,表示将所有相同的数据都标记为重复项。
  • inplace 表示是否放弃副本数据,返回新的数据,默认为False True:放弃副本,更新原数据。False:不更新原数据。
  • ignore_index 表示是否对删除重复值后的对象的行索引重新排序,默认为False。 True:重新排序。False:不重新排序。
# 删除stu_info对象中的重复值
stu_info.drop_duplicates()
'''	
	住址	姓名	年龄	序号	性别
0	苏州	张三	15		S1		女
1	南京	李四	16		S2		男
3	NaN		赵六	14		S4		男
'''

四、异常值

异常值查找

describe进行描述性分析

仅能进行连续变量的处理

import pandas as pd  # 导入数据分析库Pandas
outputPath = 'tmp/result.xls'  # 输出数据路径
data.describe().to_excel(outputPath, index=True)

根据最大值、最小值等判断异常值

箱型图

四分位距(IQR)就是上四分位与下四分位的差值。而我们通过IQR的1.5倍为标准,规定:超过上四分位+1.5倍IQR距离,或者下四分位-1.5倍IQR距离的点为异常值。

import pandas as pd
import numpy as np 
import matplotlib.pyplot as plt  # 导入图像库
stu_info=pd.DataFrame({'序号':['S1','S2','S1','S4','S4'],
                '姓名':['张三','李四','张三','赵六','赵六'],
                '性别':['女','男','女','男','男'],
                '年龄':[15,16,15,14,14],
                '分数':[24,52,53,215,35],
                '住址':['苏州','南京','苏州',np.nan,np.nan]})

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

plt.subplot(1,2,1)
stu_info[["年龄"]].boxplot(return_type='dict')
plt.subplot(1,2,2)
stu_info[["分数"]].boxplot(return_type='dict')
plt.show()

在这里插入图片描述

异常值处理

删除、替换

先将异常值替换为na,然后用dropna() 删除或进行替换

a = stu_info["分数"].quantile(0.75)
b = stu_info["分数"].quantile(0.25)
c = stu_info["分数"]
c[(c>=(a-b)*1.5+a)|(c<=b-(a-b)*1.5)]=np.nan
stu_info[["分数"]] = c
stu_info_1 = stu_info.dropna(how='any', axis=0,subset = ['分数'])
stu_info_1
'''
	住址	分数	姓名	年龄	序号	性别
0	苏州	24.0	张三	15		S1		女
1	南京	52.0	李四	16		S2		男
2	苏州	53.0	张三	15		S1		女
4	NaN		35.0	赵六	14		S4		男
'''

a = stu_info["分数"].mean()+stu_info["分数"].std()*4
b = stu_info["分数"].mean()-stu_info["分数"].std()*4
c = stu_info["分数"]
c[(c >= a) | (c <= b)] = np.nan
stu_info[["分数"]] = c
stu_info_1 = stu_info.dropna(how='any', axis=0,subset = ['分数'])
stu_info_1

五、无量纲化

特征无量纲化主要是通过特征的标准化将特征值“缩小”到同一量纲;

Min-max标准化

也称为“归一化”,是通过对原始特征进行变换,把特征值映射到[0,1]。这种方法可以将不同量纲的特征“缩小”到相同范围,变换公式如式在这里插入图片描述所示,其中,xmax表示特征最大值,xmin表示特征最小值,x表示原始特征值。

from utils import data_utils
from sklearn.preprocessing import MinMaxscaler
#导入数值型样例数据
data = data_utils.get_data()
#max-min标往化
X_MinMaxScaler = MinMaxScaler().fit_transform(data[data_utils.numeric_cols])

z-score标准化

z-score标准化是常见的特征预处理方式,线性模型在训练数据之前基本都会进行z-score 标准化。对原始特征进行变换可以把特征分布变换到均值为0,标准差为1,变换公式如式在这里插入图片描述所示,其中,μ为特征均值,\sigma为特征标准差。

在使用Min-max 标准化时,如果测试集里的特征有小于xmin或大于xmax的值,那么会导致xmin和xmax发生变化。因此在实际算法中,除非特征的取值有上下限,否则minmax标准化没有z-score标准化好用。此外,如果出现异常点,影响了最大值和最小值,那么minmax标准化的结果势必受到影响。而对于z-score标准化,如果出现少量异常点,对均值和方差的影响并不大,那么对结果的影响较小。

  • 9
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值