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,该对象的类型与源类型一样 |
notnull | isnull的否定式 |
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