pandas 数据清洗

一、检测与处理缺失值的操作

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部门姓名应发数发放时间绩效合计工资
108FalseFalseFalseFalseFalseTrueTrue
109FalseFalseFalseFalseFalseTrueTrue
110FalseFalseFalseFalseFalseTrueTrue
111FalseFalseFalseFalseFalseTrueTrue
112FalseFalseFalseFalseFalseTrueTrue
113FalseTrueFalseTrueTrueFalseTrue
114FalseTrueFalseTrueTrueFalseTrue
115FalseTrueFalseTrueTrueFalseTrue
116FalseTrueFalseTrueTrueFalseTrue
117FalseTrueFalseTrueTrueFalseTrue
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部门姓名应发数发放时间绩效合计工资
108108讲解员(6人)张凤楚3200.02020-07工资0.03200.0
109109讲解员(6人)赵聪3200.02020-07工资0.03200.0
110110讲解员(6人)钱沫琪3200.02020-07工资0.03200.0
111111讲解员(6人)苗一萌3200.02020-07工资0.03200.0
112112讲解员(6人)韩小艺3200.02020-07工资0.03200.0
113113实习孙晓娜0.0NaN3420.03420.0
114114实习王金英0.0NaN3240.03240.0
115115实习申洁0.0NaN3600.03600.0
116116实习郑开彦0.0NaN3420.03420.0
117117实习郭建萍0.0NaN3420.03420.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部门姓名应发数发放时间绩效合计工资
108108讲解员(6人)张凤楚3200.02020-07工资0.03200.0
109109讲解员(6人)赵聪3200.02020-07工资0.03200.0
110110讲解员(6人)钱沫琪3200.02020-07工资0.03200.0
111111讲解员(6人)苗一萌3200.02020-07工资0.03200.0
112112讲解员(6人)韩小艺3200.02020-07工资0.03200.0
113113实习孙晓娜0.0NaN3420.03420.0
114114实习王金英0.0NaN3240.03240.0
115115实习申洁0.0NaN3600.03600.0
116116实习郑开彦0.0NaN3420.03420.0
117117实习郭建萍0.0NaN3420.03420.0
# '姓名','应发数','绩效',这三列有空值就删掉,没有空值就不删
data.dropna(subset=['姓名','应发数','绩效'],how='any')
Unnamed: 0部门姓名应发数发放时间绩效合计工资
108108讲解员(6人)张凤楚3200.02020-07工资0.03200.0
109109讲解员(6人)赵聪3200.02020-07工资0.03200.0
110110讲解员(6人)钱沫琪3200.02020-07工资0.03200.0
111111讲解员(6人)苗一萌3200.02020-07工资0.03200.0
112112讲解员(6人)韩小艺3200.02020-07工资0.03200.0
113113实习孙晓娜0.0NaN3420.03420.0
114114实习王金英0.0NaN3240.03240.0
115115实习申洁0.0NaN3600.03600.0
116116实习郑开彦0.0NaN3420.03420.0
117117实习郭建萍0.0NaN3420.03420.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'])
nameidage
0lx112
1ss215
2ws312

2、特征重复

特征重复要求:需要是连续数值型,
通过相似度方法来判定两列值是否具有某种关系;(-1,1)
如果两列值呈1或-1相关就是正相关或负相关

通过相似度去重:这个方法只能处理数值型,不能处理类别型,类别型特征之间是无法通过相关系数来计算相关度的

data=pd.read_excel(r'meal_order_detail.xlsx')
# kendall计算相关的方法
data[['counts','amounts']].corr(method='kendall')
countsamounts
counts1.000000-0.253092
amounts-0.2530921.000000
# spearman计算相关的方法
data[['counts','amounts']].corr(method='spearman')
countsamounts
counts1.000000-0.307324
amounts-0.3073241.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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值