数据清洗---excel异常值处理(scipy)

一.导入模块

import pandas as pd
from scipy.interpolate import interp1d

二.读取excel文件

data=pd.read_excel(r'E:\pythonwork\数据分析\11.数据清洗\人事终表 (1).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
'''
print(data.notnull())   # True/False
data1=data['绩效'].notnull().sum()   # ==> .count
print(data1)        # 5

2.处理空值的方法

(1).填充空值 data.fillna

data.fillna({'部门':'实习','应发数':0,'发放时间':'2020-07工资','绩效':0},
            limit=3,            # 限制修改条数,默认是None
            inplace=True        # 填充空值的方法
            )
data['合计工资']=data['应发数']+data['绩效']
# print(data)

(2)删除空值的方法 data.dropna

data2=data.dropna(axis=0,how='all',thresh=2,subset=['部门','姓名'],inplace=False)
# 1.how='any' 有空就删,how='all' 全为空才删
# 2.thresh=6  表示当空值数量<6,则删除
# 3.subset=[],表示删除行的情况可以根据列是否为空删除行
# 4.inplace=False 默认为False不修改原表

# data2=data.dropna(axis=0,how='any')
# data2=data.dropna(axis=0,thresh=3)    # thresh最大空值数量,大于就删
# data2=data.dropna(subset=['部门','姓名','应发数'],axis=0)
# print(data)
# print(data2)

3.插值法—处理缺失值的方法

(1)线性插值:

要求x,y之间满足线性关系: y=kx+b

# 科学计数法scipy
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')   # linear 拟合线性函数,只能在当前x的范围内插值
print(Linear1([2.235]))      # [6.47]
(2) 多项式插值的方法 (非线性方程y=2*(x+1)2):

利用已知的值,拟合一个多项式:

'''拉格朗日插值,牛顿插值'''
from scipy.interpolate import lagrange
x1=np.array([0,1,2,3,4,7,8,9])           # 也可以写成x1=[0,1,2,3,4,7,8,9]
y1=np.array([2,8,18,32,50,128,162,200])  # 也可以写成y1=[2,8,18,32,50,128,162,200]
Lag=lagrange(x1,y1)
print(Lag([5,6]))
'''总结:如果用非线性函数拟合线性数据是可以的,但是用线性函数拟合非线性数据是不行的,不会报错但值不正确'''

4.检测与处理重复值

(1) 记录重复
'''series: ser.drop_duplicates()  # 没有subset参数
dataframe: df.drop_duplicates(subset=['','']) 一般偶会传入subset,
根据subset中的键判断元素是否一致,如果一致,则数据重复--删除,如果不一致则保留'''
df=pd.DataFrame({'name':['lx','ss','ws','lx'],'id':[1,2,3,1],'age':[12,15,12,12]})
print(df)
df1=df.drop_duplicates(subset=(['name','id']),inplace=True)
print(df1)
(2).特征重复
'''特征重复要求:需要是连续数值型
通过相似度的方法,判断两列是否具有某种关系: (-1,1)
通过相识度去重: 这个方法只能处理数值型,不能处理类别型,
类别特征是无法通过相关系数来计算相识度的'''
data=pd.read_excel(r'E:\pythonwork\数据分析\7.panada的创建\meal_order_detail.xlsx')
data1=data[['counts','amounts']].corr(method='kendall')
# data1=data[['counts','amounts']].corr(method='spearman')
print(data1)
(3).哑变量处理:将类别型数据转换为数值型数据
'''稀疏矩阵--返回的数值类型是一个稀疏矩阵,one-hot编码'''
x=data['dishes_name'].head()
x1=pd.get_dummies(x)
print(x1)
(4)异常值的处理
'''1.什么是异常值?
异常值是指数据中心个别数值明显偏离其余数值的数据,也称为离群点,野值:
检测异常值就是监测数据中是否有录入错误以及是否有不合理的数据'''

'''2. 3σ原则:[拉依达准则]
该法则就是假设一组检验数据只有随机误差,对原始数据进行计算处理得到标准差
按照一定的概率确定一个区间,人为误差超过这个区间就属于异常值
3σ原则仅适用于服从正态分布或者近似正态分布的数据
μ-3σ<x<μ+3σ,为正常区间的数据,此区间的概率值为0.9973'''

'''3.根据项目场景自定义阈值范围:'''
min_mask=data['amounts']<data['amounts'].mean()-data['amounts'].std()
max_mask=data['amounts']>data['amounts'].mean()+data['amounts'].std()
mask=min_mask|max_mask
data1=data.loc[mask,'amounts'].head(10)
print(data1)
(5) 连续数据离散化
''' 
分析一个问题时,某些特征是连续的, 
eg:年龄; 儿童,青年,中年,老年
'''
1.等宽法 pd.cut(数据,bins)
# --- 尽力要求区间宽度一致的,但是落到每个区间内的频数就不能保证一致了
'''
用此方法更多的关注的是区间的宽度
参数说明:bins表示区间, 当bins=一个自然数时表示区间个数,等分区间; bins=列表时表示自定义分割区间
'''
# print(data['amounts'].describe())
da2=pd.cut(data['amounts'],bins=5).value_counts()
bins=[0,25,35,56,179]
da2=pd.cut(data['amounts'],bins=bins).value_counts()
print(da2)
2.等频法 pd.qcut
# --- 尽力使的数据能均匀的落到每个区间
'''
q=int,表示切割成几个区间
q=list,表示分位数,list=[0,0.25,0.5,0.75,1]/[0,0.3,0.6]
'''
da3=pd.qcut(data['amounts'],q=10).value_counts()
# print(da3)
(6)数据标准化

当样本的数据中属性的量纲差别很大的时候,相似度的计算结果就会完全由数值大的属性支配

1.离差标准化 x’=(x-min)/(max-min) (0<=x’<=1)
'''缺点:
(1)标准化的数据最大值和最小值不能取值相同,分母为0公式不成立
(2)该方法完全取决于max与min值,当max或者min为异常值的时候标准化不准确可能出现趋于0的情况
'''
2.标准差标准化 x’=(x-μ)/σ (-inf<x’<inf)[μ:均值,σ:标准差]
'''
标准化之后μ=0,σ=1,方差为1
x'的范围是: [-np.inf,np.inf]
'''
3.小数定标标准化 x’=x/10**k (-1<x’<1, k = np.ceil( np.log10( x.abs().max() ) )
x=pd.Series([-10,20,15,16,18,21,12])

例:

x=pd.Series([-10,20,15,16,18,21,12])

# 离差标准化 [0-1]
def get_float_transform(x):
    x_new=(x-x.min())/(x.max()-x.min())
    return x_new
print(x.transform(get_float_transform))
# 标准差标准化
def get_std_transform(x):
    x_new=(x-x.mean())/x.std()
    return x_new
print(x.transform(get_std_transform))
# 小数定标标准化 [-1,1]
def get_transform(x):
    k=np.ceil(np.log10(x.abs().max()))
    x_new=x/10**k
    return x_new
print(x.transform(get_transform))
  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值