一、检测与处理缺失值的操作
import numpy as np
import pandas as pd
data=pd.read_excel(r'D:\pandas\人事终表.xlsx').tail(10)
print(data)
Unnamed: 0 部门 姓名 应发数 发放时间 绩效 合计工资
108 108 讲解员(6人) 张凤楚 3200.0 2020-07工资 NaN NaN
109 109 讲解员(6人) 赵聪 3200.0 2020-07工资 NaN NaN
110 110 讲解员(6人) 钱沫琪 3200.0 2020-07工资 NaN NaN
111 111 讲解员(6人) 苗一萌 3200.0 2020-07工资 NaN NaN
112 112 讲解员(6人) 韩小艺 3200.0 2020-07工资 NaN NaN
113 113 NaN 孙晓娜 NaN NaN 3420.0 NaN
114 114 NaN 王金英 NaN NaN 3240.0 NaN
115 115 NaN 申洁 NaN NaN 3600.0 NaN
116 116 NaN 郑开彦 NaN NaN 3420.0 NaN
117 117 NaN 郭建萍 NaN NaN 3420.0 NaN
1、检测缺失值的方法
isnull:判断元素是空值,如果是空值则返回True,否则返回False
notnull:判断元素不是空值的方法,如果不是空值则返回True,否则返回False
data.isnull()
Unnamed: 0 | 部门 | 姓名 | 应发数 | 发放时间 | 绩效 | 合计工资 | |
---|---|---|---|---|---|---|---|
108 | False | False | False | False | False | True | True |
109 | False | False | False | False | False | True | True |
110 | False | False | False | False | False | True | True |
111 | False | False | False | False | False | True | True |
112 | False | False | False | False | False | True | True |
113 | False | True | False | True | True | False | True |
114 | False | True | False | True | True | False | True |
115 | False | True | False | True | True | False | True |
116 | False | True | False | True | True | False | True |
117 | False | True | False | True | True | False | True |
data['绩效'].isnull().sum()
5
data['绩效'].notnull().sum() # 等同于count()
5
2、处理空值的方法:填、删
填充空值
data.fillna({'部门':'实习','应发数':0,'绩效':0},limit=None,inplace=True) # 填充空值的方法 limit限制修改的条数
data['合计工资']=data['应发数']+data['绩效']
data
Unnamed: 0 | 部门 | 姓名 | 应发数 | 发放时间 | 绩效 | 合计工资 | |
---|---|---|---|---|---|---|---|
108 | 108 | 讲解员(6人) | 张凤楚 | 3200.0 | 2020-07工资 | 0.0 | 3200.0 |
109 | 109 | 讲解员(6人) | 赵聪 | 3200.0 | 2020-07工资 | 0.0 | 3200.0 |
110 | 110 | 讲解员(6人) | 钱沫琪 | 3200.0 | 2020-07工资 | 0.0 | 3200.0 |
111 | 111 | 讲解员(6人) | 苗一萌 | 3200.0 | 2020-07工资 | 0.0 | 3200.0 |
112 | 112 | 讲解员(6人) | 韩小艺 | 3200.0 | 2020-07工资 | 0.0 | 3200.0 |
113 | 113 | 实习 | 孙晓娜 | 0.0 | NaN | 3420.0 | 3420.0 |
114 | 114 | 实习 | 王金英 | 0.0 | NaN | 3240.0 | 3240.0 |
115 | 115 | 实习 | 申洁 | 0.0 | NaN | 3600.0 | 3600.0 |
116 | 116 | 实习 | 郑开彦 | 0.0 | NaN | 3420.0 | 3420.0 |
117 | 117 | 实习 | 郭建萍 | 0.0 | NaN | 3420.0 | 3420.0 |
删除空值的方法
dropna参数说明
1、how=‘any’有空则删,‘all’全空才删;
2、thresh=5,表示当非空数量<5,则删除;
3、subset=[‘姓名’,‘应发数’,‘绩效’],表示删除行的时候,可以根据指定的列中缺失的情况进行判断
# axis=0 删除行;axis=1 删除列
# how=any 一行中有一个为空就删除;all全为空才删除
# thresh=5 非空的数值大于等于5,就不删
data.dropna(axis=0,how='any',thresh=5)
Unnamed: 0 | 部门 | 姓名 | 应发数 | 发放时间 | 绩效 | 合计工资 | |
---|---|---|---|---|---|---|---|
108 | 108 | 讲解员(6人) | 张凤楚 | 3200.0 | 2020-07工资 | 0.0 | 3200.0 |
109 | 109 | 讲解员(6人) | 赵聪 | 3200.0 | 2020-07工资 | 0.0 | 3200.0 |
110 | 110 | 讲解员(6人) | 钱沫琪 | 3200.0 | 2020-07工资 | 0.0 | 3200.0 |
111 | 111 | 讲解员(6人) | 苗一萌 | 3200.0 | 2020-07工资 | 0.0 | 3200.0 |
112 | 112 | 讲解员(6人) | 韩小艺 | 3200.0 | 2020-07工资 | 0.0 | 3200.0 |
113 | 113 | 实习 | 孙晓娜 | 0.0 | NaN | 3420.0 | 3420.0 |
114 | 114 | 实习 | 王金英 | 0.0 | NaN | 3240.0 | 3240.0 |
115 | 115 | 实习 | 申洁 | 0.0 | NaN | 3600.0 | 3600.0 |
116 | 116 | 实习 | 郑开彦 | 0.0 | NaN | 3420.0 | 3420.0 |
117 | 117 | 实习 | 郭建萍 | 0.0 | NaN | 3420.0 | 3420.0 |
# '姓名','应发数','绩效',这三列有空值就删掉,没有空值就不删
data.dropna(subset=['姓名','应发数','绩效'],how='any')
Unnamed: 0 | 部门 | 姓名 | 应发数 | 发放时间 | 绩效 | 合计工资 | |
---|---|---|---|---|---|---|---|
108 | 108 | 讲解员(6人) | 张凤楚 | 3200.0 | 2020-07工资 | 0.0 | 3200.0 |
109 | 109 | 讲解员(6人) | 赵聪 | 3200.0 | 2020-07工资 | 0.0 | 3200.0 |
110 | 110 | 讲解员(6人) | 钱沫琪 | 3200.0 | 2020-07工资 | 0.0 | 3200.0 |
111 | 111 | 讲解员(6人) | 苗一萌 | 3200.0 | 2020-07工资 | 0.0 | 3200.0 |
112 | 112 | 讲解员(6人) | 韩小艺 | 3200.0 | 2020-07工资 | 0.0 | 3200.0 |
113 | 113 | 实习 | 孙晓娜 | 0.0 | NaN | 3420.0 | 3420.0 |
114 | 114 | 实习 | 王金英 | 0.0 | NaN | 3240.0 | 3240.0 |
115 | 115 | 实习 | 申洁 | 0.0 | NaN | 3600.0 | 3600.0 |
116 | 116 | 实习 | 郑开彦 | 0.0 | NaN | 3420.0 | 3420.0 |
117 | 117 | 实习 | 郭建萍 | 0.0 | NaN | 3420.0 | 3420.0 |
3、插入缺失值的方法:插值法
(1)线性插值:
要求x,y之间满足线性关系:y=kx+b
interp1d(x,y,kind=‘linear’),只能在规定x范围内插值
from scipy.interpolate import interp1d
x=np.array([0,1,2,3,5])
y=np.array([2,4,6,8,12])
Linear1=interp1d(x,y,kind='linear') # 线性插值,根据x、y给个方程
print(Linear1([4])) # 只能插值,不能预测,也就是只能在0-5范围之内插值
[10.]
(2)多项式插值的方法:利用已知值,拟合一个多项式;
拉格朗日插值,牛顿差值;y=2(X+1)^2
from scipy.interpolate import lagrange
x1=[0,1,2,3,4,7,8,9]
y1=[2,8,18,32,50,128,162,200]
Larg=lagrange(x1,y1)
print(Larg([5,6]))
[72. 98.]
linear2=interp1d(x1,y1,kind='linear')
linear2([5,6])
array([ 76., 102.])
larg1=lagrange(x,y)
larg1([4])
array([10.])
总结:如果用非线性函数拟合线性的数据,是可以的;
但是用线性函数拟合非线性的数据,结果比较差。
二、检测与处理重复值
1、记录重复
df=pd.DataFrame({'name':['lx','ss','ws','lx'],
'id':[1,2,3,1],
'age':[12,15,12,12]})
print(df)
name id age
0 lx 1 12
1 ss 2 15
2 ws 3 12
3 lx 1 12
series:drop_duplicates()# 没有subset参数;
dataframe:drop_duplicates()# 一般会传入subset,根据subset中的键判断元素是否一致,如果一致则数据重复,删除,如果不一致则保留
df.drop_duplicates(subset=['name','id'])
name | id | age | |
---|---|---|---|
0 | lx | 1 | 12 |
1 | ss | 2 | 15 |
2 | ws | 3 | 12 |
2、特征重复
特征重复要求:需要是连续数值型,
通过相似度方法来判定两列值是否具有某种关系;(-1,1)
如果两列值呈1或-1相关就是正相关或负相关
通过相似度去重:这个方法只能处理数值型,不能处理类别型,类别型特征之间是无法通过相关系数来计算相关度的
data=pd.read_excel(r'meal_order_detail.xlsx')
# kendall计算相关的方法
data[['counts','amounts']].corr(method='kendall')
counts | amounts | |
---|---|---|
counts | 1.000000 | -0.253092 |
amounts | -0.253092 | 1.000000 |
# spearman计算相关的方法
data[['counts','amounts']].corr(method='spearman')
counts | amounts | |
---|---|---|
counts | 1.000000 | -0.307324 |
amounts | -0.307324 | 1.000000 |
3、哑变量处理:将类别型数据转化为数值型数据
返回的数值类型是一个稀疏矩阵,one-hot编码
x=data['dishes_name'].head()
x
0 蒜蓉生蚝
1 蒙古烤羊腿
2 大蒜苋菜
3 芝麻烤紫菜
4 蒜香包
Name: dishes_name, dtype: object
df=pd.get_dummies(x)
print(df)
大蒜苋菜 芝麻烤紫菜 蒙古烤羊腿 蒜蓉生蚝 蒜香包
0 0 0 0 1 0
1 0 0 1 0 0
2 1 0 0 0 0
3 0 1 0 0 0
4 0 0 0 0 1
4、异常值处理:
(1)什么是异常值?
异常值是指数据中个别的数值明显偏离其余数值的数据,也称为离群点(野值);
检测异常值就是检测数据中心是否有录入错误以及数据值是否有不合理的数据。
(2)3σ原则:【拉依达准则】
该法则就是假设一组检验数据只有随机误差,对原始数据进行计算处理得到标准差
按照一定的概率确定一个区间,认为误差超过这个区间就属于异常值。
3σ原则仅适用于服从正态分布,或者近似正态分布的数据;
μ-3σ<x<μ+3σ,为正常区间数据,此区间的概率值为0.9973
(3)根据项目场景自定义阈值范围;
data['amounts'].describe()
count 2779.000000
mean 45.337172
std 36.808550
min 1.000000
25% 25.000000
50% 35.000000
75% 56.000000
max 178.000000
Name: amounts, dtype: float64
min_mask=data['amounts']<data['amounts'].mean()-3*data['amounts'].std()
max_mask=data['amounts']>data['amounts'].mean()+3*data['amounts'].std()
mask=min_mask|max_mask
data.loc[mask,'amounts']
11 175
65 169
102 175
122 175
130 178
...
2667 175
2676 159
2696 178
2698 158
2716 178
Name: amounts, Length: 130, dtype: int64
5、连续数据离散化
分析一个问题时,某些特征是连续的,eg:年龄;什么年龄段的人倾向买皮肤
儿童,青年,中年,老年
1 等宽法(cut):尽力要求区间宽度一致的,但是落到每个区间内的频数就不能保证一致了。
用此方法更多的是关注区间的宽度;
参数说明:bins:表示的是区间,当bins中传入为数值的时候表示区间的个数;当bins中传入为list时,为自定义的分割区间
pd.cut(data['amounts'],bins=5).value_counts()
(0.823, 36.4] 1488
(36.4, 71.8] 885
(71.8, 107.2] 233
(142.6, 178.0] 130
(107.2, 142.6] 43
Name: amounts, dtype: int64
print(data['amounts'].describe())
count 2779.000000
mean 45.337172
std 36.808550
min 1.000000
25% 25.000000
50% 35.000000
75% 56.000000
max 178.000000
Name: amounts, dtype: float64
bins=[0,25,35,56,178]# 前开后闭所以从0开始
pd.cut(data['amounts'],bins=bins).value_counts()
(0, 25] 738
(25, 35] 736
(56, 178] 666
(35, 56] 639
Name: amounts, dtype: int64
2 等频法:尽力使得数据能够均匀的落到每个区间:
q:int,表示切割成几个区间;
q:list,是分位数,list=[0,0.25,0.5,0.75,1],此处可以自定义概率值。
pd.qcut(data['amounts'],q=4).value_counts()
(0.999, 25.0] 738
(25.0, 35.0] 736
(56.0, 178.0] 666
(35.0, 56.0] 639
Name: amounts, dtype: int64
6、数据标准化
当样本中属性的量纲差别很大的时候,相似度的计算结果就会完全的由数值大的属性支配;
相似度==>距离(d)
d ab=0.2 ab之间距离小更相似
d ac=1
1、离差标准化:
x’=(x-min)/(max-min)
x’范围:0<=x’<=1
缺点:(1)标准化的数据不能取值全一样,如果全一样,分母为0,公式不成立。
(2)该方法完全取决于max与min,当max或min值为异常值的时候,标准化不准确,可能会出现趋于0的情况
2、标准差标准化【通用】
标准差标准化之后的数据满足:均值为0,方差为1
x’=(x-μ)/σ
μ:均值
σ:标准差
x’范围为:-np.inf~np.inf
3、小数定标标准化:
x’=x/10**k
-1<x’<1
难点:找到k:np.ceil(np.log10(x.abs().max()))
ceil向上取整
# eg:小数定标标准化的案例:
x=pd.Series([-10,20,15,16,21,18,12])
k=np.ceil(np.log10(x.abs().max()))
x/10**k
0 -0.10
1 0.20
2 0.15
3 0.16
4 0.21
5 0.18
6 0.12
dtype: float64
# 小数定标标准化函数[-1,1]
def get_xiaoshu_transform(x):
k=np.ceil(np.log10(x.abs().max()))
x_new=x/10**k
return x_new
# 离差标准化:[0,1]
def get_licha_transform(x):
x_new=(x-x.min())/(x.max()-x.min())
return x_new
# 标准差标准化(负无穷,正无穷)
def get_scale_transform(x):
x_new=(x-x.mean())/x.std()
return x_new
x.transform(get_scale_transform)
0 -2.172524
1 0.643711
2 0.174338
3 0.268213
4 0.737585
5 0.455962
6 -0.107285
dtype: float64