【Python】数据处理.pandas数据预处理.清洗数据

网友投稿 360 2022-08-25

【Python】数据处理.pandas数据预处理.清洗数据

文章目录

​​pandas.数据预处理.清洗数据​​

​​一、处理重复值​​

​​1.1 处理记录重复​​​​1.2 处理特征重复​​

​​二、处理缺失值​​

​​2.1 删除法​​​​2.2 替换法​​​​2.3 插值法​​

​​三、处理异常值​​

​​3.1 3∂原则​​​​3.2 箱线图分析​​

pandas.数据预处理.清洗数据

数据重复会导致数据的方差变现哦,数据分布发生比较大变化。缺失会导致样本信息减少,不仅增加了数据分析的难度,而且会导致数据分析的结果产生偏差。异常值则会产生‘伪回归’。因此需要对数据进行检测,查询是否有重复值、缺失值和异常值,并且对所发现的异常数据进行适当的调整。

一、处理重复值

常见的数据重复分为两种:记录重复 (存在一个或几个特征的某几条记录值完全相同。)特征重复 (存在一个或多个特征的名称不同,但是数据完全相同。)

1.1 处理记录重复

利用list去重

import pandas as pddetail = pd.read_csv('data/detail.csv',index_col=0,encoding='gbk')# 定义去重函数def delRep(list1): list2=[] for i in list1: if i not in list2: list2.append(i) return list2# 去重# 提取dishes_name所有数据转化为listdishes = list(detail['dishes_name'])print('去重之前的所有菜品总数为:',len(dishes))dish = delRep(dishes)print('去重之后的所有菜品总数为:',len(dish))去重之前的所有菜品总数为: 10037去重之后的所有菜品总数为: 145

利用set唯一性去重

# 利用set方法去重print('去重之前的所有菜品总数为:',len(dishes))dish_set = set(dishes)print('去重之后的所有菜品总数为:',len(dish_set))去重之前的所有菜品总数为: 10037去重之后的所有菜品总数为: 145

drop_duplicates()方法

# 对dashes_name去重dishes_name = detail['dishes_name'].drop_duplicates()print('去重之后的所有菜品总数为:',len(dishes_name))去重之后的所有菜品总数为: 145

#多列去重print('去重之前订单详情表的形状为:',detail.shape)shapeDet = detail.drop_duplicates(subset=['order_id','emp_id'])print('去重之后订单详情表的形状为:',shapeDet.shape)shapeDet.to_csv('data/shapeDet.csv',sep=',',index=True)去重之前订单详情表的形状为: (10037, 18)去重之后订单详情表的形状为: (942, 18)

​​​​

1.2 处理特征重复

要去除特征之间的的重复,可以利用特征间的相似度将两个相似度为1的特征去掉一个。去除特征重复的方法主要有两个:corr()方法DataFrame.equals()方法

corr()方法

在pandas中,相似度的计算方法为corr。使用该方法在计算相似度的时候,默认为pearson法(method还提供了spearman、kendall)。

# 求取销售量和销售价的相似度corrDet = detail[['counts','amounts']].corr(method='kendall')print('销量和售价的Kendall法相似度矩阵为:\n',corrDet)#销量和售价的Kendall法相似度矩阵为: counts amountscounts 1.000000 -0.229968amounts -0.229968 1.000000corrDet2 = detail[['counts','amounts']].corr(method='spearman')print('销量和售价的spearman法相似度矩阵为:\n',corrDet2)#销量和售价的spearman法相似度矩阵为: counts amountscounts 1.000000 -0.229968amounts -0.229968 1.000000corrDet1 = detail[['counts','amounts','dishes_name']].corr(method='kendall')print('销量和售价的Kendall法相似度矩阵为:\n',corrDet1)#销量和售价的Kendall法相似度矩阵为: counts amountscounts 1.000000 -0.229968amounts -0.229968 1.000000

但是通过相似度矩阵去重存在一个弊端,就是它只能够对数值型重复特征去重,类别型特征之间无法通过计算相似度系数来衡量相似度,如第三段代码,dishes_name为类别型数据,通过相似度矩阵法无法计算出其相似度矩阵。

DataFrame.equals()方法

import pandas as pddetail = pd.read_csv('data/detail.csv',index_col=0,encoding='gbk')# 定义求取特征是否完全相同的矩阵的函数def featureequals(df): dfequals = pd.DataFrame([],columns=df.columns,index=df.columns) for i in df.columns: for j in df.columns: dfequals.loc[i,j] = df.loc[:,i].equals(df.loc[:,j]) return dfequalsdetequals = featureequals(detail)print('detail特征相等矩阵的前5行5列为:\n',detequals.iloc[:5,:5])detequals.to_csv('data/detequals.csv',sep=',',index=True)#detail特征相等矩阵的前5行5列为: order_id dishes_id logicprn_name parent_class_name dishes_nameorder_id True False False False False dishes_id False True False False False logicprn_name False False True True False parent_class_name False False True True False dishes_name False False False False True # 遍历所有数据lendet = detequals.shape[0] #18dupcol = [] for k in range(lendet): #(0-17) for l in range(k+1,lendet): #(1-18) if detequals.iloc[k,l] & (detequals.columns[l] not in dupcol): dupcol.append(detequals.columns[l]) # 进行去重操作print('需要删除的列为:',dupcol)detail.drop(dupcol,axis=1,inplace=True)print('删除多余列后detail的特征数目为:',detail.shape[1])detail.to_csv('data/detail_drop.csv',sep=',',index=True)#需要删除的列为: ['parent_class_name', 'cost', 'discount_amt', 'discount_reason', 'kick_back', 'add_info', 'bar_code', 'add_inprice']#删除多余列后detail的特征数目为: 10

通过遍历去重时,利用二重循环,k控制行数,l控制列数。

k取值范围

l取值范围

当前状态

k=0

l=1-17

没遇到True下一行;

k=1

l=2-17

没遇到True下一行;

k=2

l=3-17

遇到True,将True对应该列的列名存入drocol(被删数组),保留本列数据

drocol=[‘parent_class_name’, ‘cost’, ‘discount_amt’, ‘discount_reason’, ‘kick_back’, ‘add_info’, ‘bar_code’]

(分别对应下图中的第4行中的六个绿色填充块)

k=3

l=4-17

遇到True,由于此时所对应的列名已存入,继续下一行遍历;

k=4

l=5-17

没遇到True下一行;

k=5

l=6-17

遇到True,drocol中没有该列字段名,存入,继续下一行遍历;

如此反复查询。

最后我们将特征去重后的数据保存为csv文件。打开后,刚开始以为出错了,如下图所示,一共有11列,但是上面的去重结过为10列。再仔细研究后发现关键在下面这段代码,我们在读取文件的时候,将原本的第一列已经设置为了index。

print('detail_drop的索引为:\n',detail.index)#detail_drop的索引为: Int64Index([2956, 2958, 2961, 2966, 2968, 1899, 1902, 1906, 1907, 1908, ... 5682, 5377, 5680, 5378, 5685, 5683, 5686, 5379, 5380, 5688], dtype='int64', name='detail_id', length=10037)

​​​​

二、处理缺失值

数据中某个或某些特征的值是不完整的,这些值被称为缺失值。pandas提供了识别缺失值的方法isnull和识别非缺失值的方法notnull,两种方法均返回布尔值:True\False.

print('detail每个特征缺失的数目为:\n',detail.isnull().sum())print('detail每个特征非缺失的数目为:\n',detail.notnull().sum())detail每个特征缺失的数目为: detail每个特征非缺失的数目为: order_id 0 order_id 10037dishes_id 0 dishes_id 10037logicprn_name 10037 logicprn_name 0dishes_name 0 dishes_name 10037itemis_add 0 itemis_add 10037counts 0 counts 10037amounts 0 amounts 10037place_order_time 0 place_order_time 10037picture_file 0 picture_file 10037emp_id 0 emp_id 10037dtype: int64 dtype:

​​​​

2.1 删除法

删除法是指将含有缺失值的特征或者记录删除。删除法同样分为:删除观测记录、删除观测特征。它属于通过减少样本量来换取信息完整度的一种方法,是一种最简单的缺失值处理方法。

pandas.DataFrame.dropna(self,axis=0,how='any',thresh=None,subset=None,inplace=False)

参数

说明

axis

接受0或1,删除行或列,默认为0删除行

how

接受特定string,表示删除的形式。any表示只要存在缺失值就执行,all表示只有当全部为缺失值时才执行。默认‘any’

subset

接受array。表示进行去重的列/行。默认None,表示所有行或列。

inplace

接受boolean。表示是否在原表上进行操作。

print('去除缺失列前detail的形状为:',detail.shape)print('去除缺失列后detail的形状为:',detail.dropna(axis=1,how='any').shape)去除缺失列前detail的形状为: (10037, 10)去除缺失列后detail的形状为: (10037, 9)

​​​​

2.2 替换法

替换法是指用一个特定的值替换缺失值。数值型:通常利用其均值、中位数、众数等来替代类别型:通常选择使用众数来替换缺失值。

pandas.DataFrame.filna(value=None,method=None,axis=None,inplace=False,limit=None)

参数

说明

value

接受scalar、dict、Series或DataFrame。表示用于替换缺失值的值

method

接受待定string。backfill或bfill表示使用下一个非缺失值来填补;pad或ffill表示使用上一个非缺失值来填补缺失值,默认为null。

axis

接受0或1,表示轴向,默认为1。

limit

接受int,表示填补缺失值的个数上限,超过则不进行填补。 如果指定了方法,则这是连续的NaN值的前向/后向填充的最大数量。 换句话说,如果连续NaN数量超过这个数字,它将只被部分填充。 如果未指定方法,则这是沿着整个轴的最大数量,其中NaN将被填充。 如果不是无,则必须大于0。

detail_fillna=detail.fillna(-99)print('detail中每个特征缺失的数目为:/n',detail.isnull().sum())detail_fillna.to_csv('data/detail_fillna.csv',sep=',',index=True)detail中每个特征缺失的数目为: order_id 0dishes_id 0logicprn_name 0dishes_name 0itemis_add 0counts 0amounts 0place_order_time 0picture_file 0emp_id 0dtype:

​​​​

2.3 插值法

常用的插值法有线性插值、多项式插值和样条插值。线性插值:针对已知的值求出线性方程,通过求解线性方程来得到缺失值。多项式插值:利用已知的值拟合一个多项式,再利用该多项式求解缺失值。常见的有牛顿插值、拉格朗日插值。 样条插值:以可变样条来做出一条经过一系列点的光滑曲线。插值样条由一些多项式构成,每一个多项式都由相邻两个数据点决定,以保证两个相邻多项式及其导数在连接处连续。

## 线性插值import numpy as npfrom scipy.interpolate import interp1dx=np.array([1,2,3,4,5,8,9,10]) ##创建自变量xy1=np.array([2,8,18,32,50,128,162,200]) ##创建因变量y1y2=np.array([3,5,7,9,11,17,19,21]) ##创建因变量y2LinearInsValue1 = interp1d(x,y1,kind='linear') ##线性插值拟合x,y1LinearInsValue2 = interp1d(x,y2,kind='linear') ##线性插值拟合x,y2print('当x为6、7时,使用线性插值y1为:',LinearInsValue1([6,7]))print('当x为6、7时,使用线性插值y2为:',LinearInsValue2([6,7]))当x为6、7时,使用线性插值y1为: [ 76. 102.]当x为6、7时,使用线性插值y2为: [13. 15.]

##多项式插值## 拉格朗日插值from scipy.interpolate import lagrangeLargeInsValue1 = lagrange(x,y1) ##拉格朗日插值拟合x,y1LargeInsValue2 = lagrange(x,y2) ##拉格朗日插值拟合x,y2print('当x为6,7时,使用拉格朗日插值y1为:',LargeInsValue1([6,7]))print('当x为6,7时,使用拉格朗日插值y2为:',LargeInsValue2([6,7]))当x为6,7时,使用拉格朗日插值y1为: [72. 98.]当x为6,7时,使用拉格朗日插值y2为: [13. 15.]

##样条插值from scipy.interpolate import spline##样条插值拟合x,y1SplineInsValue1 = spline(x,y1,xnew=np.array([6,7]))##样条插值拟合x,y2SplineInsValue2 = spline(x,y2,xnew=np.array([6,7]))print('当x为6,7时,使用样条插值y1为:',SplineInsValue1)print('当x为6,7时,使用样条插值y2为:',SplineInsValue2)

​​​​

三、处理异常值

异常值就是指数据中个别值的数值明显偏离其余的数值,有时也成为离群点。检测异常值就是检测数据中是否有输入错误及是否含有不合理的数据。 常用的异常值检测方法主要有:3∂原则箱线图分析

3.1 3∂原则

# 定义3∂原则来识别异常数值的函数def outrange(ser1): boolind = (ser1.mean()-3*ser1.std()>ser1) | (ser1.mean()+3*ser1.var()

​​​​

3.2 箱线图分析

​​箱线图​​提供了识别与异常值的一个标准,即异常值通常被定义为小于QL-1.5IQL或大于QU+1.5IQL的值。其判断异常值的标准以四分位数和四分位数之差为基础。QL被称为下四分位数,表示全部观察值中有1/4的数据值比它小,QU被称为上四分位数,表示全部观察值中有1/4比它大;IQR称为四分位数间距,是上四分位数QU与下四分位数QL之差。四分位数给出了数据分布的中心、散布和形状的某种指示,具有一定的鲁棒性,即25%的数据可以变得任意远,而不会很大的扰动四分位数,所以异常值通常不能对这个标准施加影响。

import matplotlib.pyplot as plt# 设置画布plt.figure(figsize=(10,8))# 绘制箱线图p = plt.boxplot(detail['counts'].values,notch=True)outlier1 = p['fliers'][0].get_ydata() #fliers为异常值的标签plt.savefig('tmp/菜品异常数据识别.png')plt.show()print('销售量异常值个数为:',len(outlier1))print('销售量数据异常值的最大值为:',outlier1.max())print('销售量数据异常值的最小值为:',outlier1.min())

outlier1 = p['fliers'][0].get_ydata()

​​​​

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:借势土味营销品牌应该如何做?(土味宣传文案)
下一篇:【Python】数据分析.pandas数据预处理.标准化数据
相关文章

 发表评论

暂时没有评论,来抢沙发吧~