Python学习4之pandas数据预处理

Python学习4之pandas

本系列文章用于以后编写代码直接调用某些代码,也用作一个学习后的记录,参考书籍为《Python数据分析与应用》,黄红梅,张良均主编,张凌,施兴,周东平副编,中国工信出版集团,人民邮电出版社,ISBN:9787115373045,文章附有代码和数据,学习起来较为容易



前言

pandas包的使用,主要是数据预处理相关的知识,包括数据合并的原理与方法,数据清洗的基本方法,数据标准化的方法,常用的数据转换方法,都是数据分析的常见预处理方法。


一、合并数据

主要包括横向或纵向堆叠合并数据和主键合并数据,重叠合并数据。

1.堆叠合并数据

包含横向堆叠和纵向堆叠数据,需注意。
横纵向堆叠都可以使用concat函数,除此之外,纵向堆叠可以使用append函数。
使用concat堆叠时候其中join参数可以选择inner或者outer代表内连接和外连接,与MySQL有一定的相同。

代码如下(示例):

import pandas as pd
import numpy as np
detail1 = pd.read_excel('meal_order_detail.xlsx',sheetname='meal_order_detail1')
#索引相同的横向堆叠数据
df1 = detail1.iloc[:,:10] ##取出detail1的前10列数据
df2 = detail1.iloc[:,10:] ##取出detail1的后9列数据
print('合并df1的大小为%s,df2的大小为%s。'%(df1.shape,df2.shape))
print('外连接合并后的数据框大小为:',pd.concat([df1,df2],
        axis=1,join='inner').shape)
print('内连接合并后的数据框大小为:',pd.concat([df1,df2],
        axis=1,join='outer').shape)

#表名相同的纵向堆叠
df3 = detail1.iloc[:1500,:] ##取出detail1前1500行数据
df4 = detail1.iloc[1500:,:] ##取出detail1的1500后的数据
print('合并df3的大小为%s,df4的大小为%s。'%(df3.shape,df4.shape))
print('内连接纵向合并后的数据框大小为:',pd.concat([df3,df4],
        axis=1,join='inner').shape)
print('外连接纵向合并后的数据框大小为:',pd.concat([df3,df4],
        axis=1,join='outer').shape)
#append方法纵向堆叠
print('堆叠前df3的大小为%s,df4的大小为%s。'%(df3.shape,df4.shape))
print('append纵向堆叠后的数据框大小为:',df3.append(df4).shape)

2.主键合并数据

主键合并,即通过一个或多个键键两个数据集的行连接起来,类似于SQL中的join,使用merge函数,除此之外,join方法也可以实现部分主键合并的功能。

注意merge和join两种合并数据对数据类型的要求有细微的差别,注意看函数介绍。

代码如下(示例):

import pandas as pd
import numpy as np
detail1 = pd.read_excel('meal_order_detail.xlsx',sheetname='meal_order_detail1')
order = pd.read_csv('meal_order_info.csv',sep=',',encoding='gb18030') ##读取订单信息表
##info_id转换为字符串格式,为合并做准备
order['info_id'] = order['info_id'].astype('str') 
detail1['order_id'] = detail1['order_id'].astype('str')
## 订单详情表和订单信息表都有订单编号
##在订单详情表中为order_id,在订单信息表中为info_id
#merge方法实现主键合并
order_detail = pd.merge(detail1,order,left_on='order_id',right_on = 'info_id')
print('detail1订单详情表的原始形状为:',detail1.shape)
print('order订单信息表的原始形状为:',order.shape)
print('订单详情表和订单信息表主键合并后的形状为:',order_detail.shape)
import pandas as pd
import numpy as np
detail1 = pd.read_excel('meal_order_detail.xlsx',sheetname='meal_order_detail1')
order = pd.read_csv('meal_order_info.csv',sep=',',encoding='gb18030') ##读取订单信息表
##info_id转换为字符串格式,为合并做准备
order['info_id'] = order['info_id'].astype('str') 
#detail1['order_id'] = detail1['order_id'].astype('str')
#注意更改数据类型后不可使用
order.rename({'info_id':'order_id'},inplace=True)
order_detail1 = detail1.join(order,on='order_id',rsuffix='1')
print('订单详情表和订单信息表join合并后的形状为:',order_detail1.shape)

3.重叠合并数据

数据分析过程中可能遇到两根数据的内容几乎一致,特征相同,但其中数据有缺失,这时候就需要重叠合并数据,让数据更完善,通过combine_first函数来实现。

代码如下(示例):

import numpy as np
import pandas as pd
##建立两个字典,除了ID外,别的特征互补
dict1 = {'ID':[1,2,3,4,5,6,7,8,9],
         'System':['win10','win10',np.nan,'win10',
                np.nan,np.nan,'win7','win7','win8'],
      'cpu':['i7','i5',np.nan,'i7',np.nan,np.nan,'i5','i5','i3']}

dict2 = {'ID':[1,2,3,4,5,6,7,8,9],
         'System':[np.nan,np.nan,'win7',np.nan,
                'win8','win7',np.nan,np.nan,np.nan],
        'cpu':[np.nan,np.nan,'i3',np.nan,'i7',
                'i5',np.nan,np.nan,np.nan]}
## 转换两个字典为DataFrame
df5 = pd.DataFrame(dict1)
df6 = pd.DataFrame(dict2)
print('经过重叠合并后的数据为:\n',df5.combine_first(df6))

二、清洗数据

数据重复会带来各种问题,如方差变小,需要进行处理重复值,缺失值,异常值。

1.检测处理重复值

重复值分两种,一种是记录重复,一个或多个特征的某几条记录完全相同,一种是特征重复,一个或多个特征名称不同但数据完全相同。
记录重复可以采用不同方法去重,可以通过list函数,set特性,drop_duplicates函数去重。
注意set去重会导致数据的排列发生变化,drop_duplicates方法只对DataFrame或者series有效,不会改变数据原始排列。
特征重复可以通过特征间的相似度来排除,通过corr函数计算相似度,默认为pearson相似度。除此之外还可以通过equals方法去重。
代码如下(示例):

import pandas as pd
detail = pd.read_csv('detail.csv',index_col=0,encoding = 'gbk')
#记录重复去重
##方法一,利用list函数
##定义去重函数
def delRep(list1):
    list2=[]
    for i in list1:
        if i not in list2:
            list2.append(i)
    return list2 
## 去重
dishes=list(detail['dishes_name']) ##将dishes_name从数据框中提取出来
print('去重前菜品总数为:',len(dishes)) 
dish = delRep(dishes) ##使用自定义的去重函数去重
print('方法一去重后菜品总数为:',len(dish))

##方法二,利用set函数去重
print('去重前菜品总数为:',len(dishes)) 
dish_set = set(dishes) ##利用set的特性去重
print('方法二去重后菜品总数为:',len(dish_set))

#方法三,利用drop_duplicates函数去重
##对dishes_name去重
dishes_name = detail['dishes_name'].drop_duplicates()
print('drop_duplicates方法去重之后菜品总数为:',len(dishes_name))
# 利用drop_duplicates函数去重多列
print('去重之前订单详情表的形状为:', detail.shape)
shapeDet = detail.drop_duplicates(subset = ['order_id',
    'emp_id']).shape
print('依照订单编号,会员编号去重之后订单详情表大小为:', shapeDet)

## 特征重复去重
#利用corr函数求取kendall法的相似度矩阵,只能对数值型特征求取
## 求取销量和售价的相似度
corrDet = detail[['counts','amounts']].corr(method='kendall')
print('销量和售价的kendall相似度为:\n',corrDet)
# 存在类别数据,自动不显示其计算的相似度
corrDet1 = detail[['dishes_name','counts',
    'amounts']].corr(method='pearson')
print('菜品名称,销量和售价的pearson相似度为:\n',corrDet1)

# 利用DataFrame.equals方法去重
##定义求取特征是否完全相同的矩阵的函数
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 dfEquals
## 应用上述函数
detEquals=FeatureEquals(detail)
print('detail的特征相等矩阵的前5行5列为:\n',detEquals.iloc[:5,:5])
##遍历所有数据进而去重
lenDet = detEquals.shape[0]
dupCol = []
for k in range(lenDet):
    for l in range(k+1,lenDet):
        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])

2.检测与处理缺失值

在数据分析中,缺失值处理也很重要,其检测通过notnull或者isnall函数来确定,均返回布尔值。

代码如下(示例):

import pandas as pd
detail = pd.read_csv('detail.csv',index_col=0,encoding = 'gbk')
#利用isnull和otnull函数计算缺失值和非缺失值
print('detail每个特征缺失的数目为:\n',detail.isnull().sum())
print('detail每个特征非缺失的数目为:\n',detail.notnull().sum())

在数据分析中,缺失值直接删除并不好,但在数据很大的情况下,也可以简单处理,用dropna函数删除。替换一般更常用做缺失值的处理方法,可以替换为均值,中位数,众数等,用fillna函数替换。再或者用插值法来替换缺失值,通过SciPy库中的不同插值方法来插值替换。

代码如下(示例):

import pandas as pd
detail = pd.read_csv('detail.csv',index_col=0,encoding = 'gbk')
# 处理缺失值方法
#方法一,直接删除,使用dropna函数
print('去除缺失的列前detail的形状为:', detail.shape)
print('去除缺失的列后detail的形状为:',
    detail.dropna(axis = 1,how ='any').shape)

# 方法二,使用fillna函数直接替换缺失值
detail = detail.fillna(-99)
print('detail每个特征缺失的数目为:\n',detail.isnull().sum())

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

## 拉格朗日插值
from scipy.interpolate import lagrange
LargeInsValue1 = lagrange(x,y1) ##拉格朗日插值拟合x,y1
LargeInsValue2 = lagrange(x,y2) ##拉格朗日插值拟合x,y2
print('当x为6,7时,使用拉格朗日插值y1为:',LargeInsValue1([6,7]))
print('当x为6,7时,使用拉格朗日插值y2为:',LargeInsValue2([6,7]))

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

3.检测与处理异常值

在数据分析中,异常值指明显偏离其余数据的数值,一般不可以直接删除,需要分析为何出现,如果是记录错误则可以删除,如果是特殊情况需要慎重考虑,异常值也称之为离群点。一般通过 3 σ 3\sigma 3σ法则来确定,或者通过箱线图来寻找异常值。

代码如下(示例):

import pandas as pd
import numpy as np
detail = pd.read_csv('detail.csv',index_col=0,encoding = 'gbk')
## 定义拉依达准则(3sigma)识别异常值函数
def outRange(Ser1):
    boolInd = (Ser1.mean()-3*Ser1.std()>Ser1) | \
    (Ser1.mean()+3*Ser1.var()< Ser1)
    index = np.arange(Ser1.shape[0])[boolInd]
    outrange = Ser1.iloc[index]
    return outrange
outlier = outRange(detail['counts'])
print('使用拉依达准则判定异常值个数为:',outlier.shape[0])
print('异常值的最大值为:',outlier.max())
print('异常值的最小值为:',outlier.min())

# 代码 菜品售价箱线图识别异常值
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.show()
print('销售量数据异常值个数为:',len(outlier1))
print('销售量数据异常值的最大值为:',max(outlier1))
print('销售量数据异常值的最小值为:',min(outlier1))

三、标准化数据

标准化数据在数据分析,机器学习中很常用到,标准化后分析更好,主要讲离差标准化,标准差标准化,小数定标标准化数据。

1.离差标准化数据

一种线性变换,映射到【0,1】中。
代码如下(示例):

import pandas as pd
import numpy as np
detail = pd.read_csv('detail.csv', index_col=0,encoding = 'gbk')
## 自定义离差标准化函数
def MinMaxScale(data):
    data=(data-data.min())/(data.max()-data.min())
    return data
##对菜品订单表售价和销量做离差标准化
data1=MinMaxScale(detail['counts'])
data2=MinMaxScale(detail ['amounts'])
data3=pd.concat([data1,data2],axis=1)
print('离差标准化之前销量和售价数据为:\n',
    detail[['counts','amounts']].head())
print('离差标准化之后销量和售价数据为:\n',data3.head())

2.标准差标准化数据

也叫做零均值标准化或者 z z z分数标准化,用途广泛,处理后,数据的均值为0,标准差为1。
代码如下(示例):

import pandas as pd
import numpy as np
detail = pd.read_csv('detail.csv', index_col=0,encoding = 'gbk')
##自定义标准差标准化函数
def StandardScaler(data):
    data=(data-data.mean())/data.std()
    return data
##对菜品订单表售价和销量做标准化
data4=StandardScaler(detail['counts'])
data5=StandardScaler(detail['amounts'])
data6=pd.concat([data4,data5],axis=1)
print('标准差标准化之前销量和售价数据为:\n',
    detail[['counts','amounts']].head())
print('标准差标准化之后销量和售价数据为:\n',data6.head())

3.标小数定标标准化数据

将数据映射到【-1,1】,移动的小数位数取决于数据绝对值的最大值,其转化公式如下。
X ∗ = X / 1 0 k X_* =X/10^k X=X/10k
代码如下(示例):

import pandas as pd
import numpy as np
detail = pd.read_csv('detail.csv', index_col=0,encoding = 'gbk')
##自定义小数定标差标准化函数
def DecimalScaler(data):
    data=data/10**np.ceil(np.log10(data.abs().max()))
    return data
##对菜品订单表售价和销量做标准化
data7=DecimalScaler(detail['counts'])
data8=DecimalScaler(detail['amounts'])
data9=pd.concat([data7,data8],axis=1)
print('小数定标标准化之前的销量和售价数据:\n',
    detail[['counts','amounts']].head())
print('小数定标标准化之后的销量和售价数据:\n',data9.head())

四、转换数据

1.哑变量处理类别型数据

有些数据时哑变量,不能直接用来建模,需要先处理,哑变量也即有些数据是类别型数据,无法直接建模,需要先处理,通过get_dummies即可处理。
代码如下(示例):

import pandas as pd
import numpy as np
detail = pd.read_csv('detail.csv',encoding = 'gbk')
data=detail.loc[0:5,'dishes_name']   ##抽取部分数据做演示
print('哑变量处理前的数据为:\n',data)
print('哑变量处理后的数据为:\n',pd.get_dummies(data))

2.离散化连续型数据

有些算法,尤其是分类算法如ID3决策树和Apriori算法都要求数据是离散的,这个时候就需要离散化连续数据了。有等宽法,等频法,聚类分析法(一维)。

等宽法是将数据分成具有相同宽度的区间,区间的个数有数据本身的特点决定或者由用户指定,与制作频率分布表类似,有cut函数使用。
其缺点是对数据分布有较高要求,如数据分布不均匀,那么各类数目也非常不均匀,效果不好。

cut函数虽然不能直接实现等频离散化,但可以定义来实现。

一维聚类的方法包含两个步骤,首先使用聚类算法(如K-means算法)进行聚类;然后处理聚类得到的簇,为合并到一个簇的数据做同一种标记。
聚类分析的离散化方法需要用户指定簇的个数,用来决定产生的区间数。
代码如下(示例):

import pandas as pd
import numpy as np
detail = pd.read_csv('detail.csv',encoding = 'gbk')
#等宽法
price = pd.cut(detail['amounts'],5)
print('离散化后5条记录售价分布为:\n' ,price.value_counts())
##自定义等频法离散化函数
def SameRateCut(data,k):
    w=data.quantile(np.arange(0,1+1.0/k,1.0/k))
    data=pd.cut(data,w)
    return data
result=SameRateCut(detail['amounts'],5).value_counts()   ##菜品售价等频法离散化
print('菜品数据等频法离散化后各个类别数目分布状况为:','\n',result)
#自定义数据k-Means聚类离散化函数
def KmeanCut(data,k):
    from sklearn.cluster import KMeans #引入KMeans
    kmodel=KMeans(n_clusters=k)   #建立模型
    kmodel.fit(data.values.reshape((len(data), 1)))    #训练模型
    c=pd.DataFrame(kmodel.cluster_centers_).sort_values(0)   #输出聚类中心并排序
    w=c.rolling(2).mean().iloc[1:]    #相邻两项求中点,作为边界点
    w=[0]+list(w[0])+[data.max()]    #把首末边界点加上
    data=pd.cut(data,w)
    return data
#菜品售价等频法离散化
result=KmeanCut(detail['amounts'],5).value_counts()
print('菜品售价聚类离散化后各个类别数目分布状况为:','\n',result)

总结

提示:本文章简单介绍了pandas包的数据预处理用法。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Python中,pandas是一个常用的数据处理库,可以用于数据的读取、清洗、转换和分析等操作。其中,pandas提供了多种功能和方法来进行数据预处理。 其中,关于数据的重复处理,可以使用DataFrame的duplicated方法来判断各行是否是重复行。这个方法返回一个布尔型Series,表示各行是否是重复行。例如,在一个DataFrame中,可以使用data.duplicated()来查看各行是否是重复行。 此外,在数据预处理中,Python内置的None值也会被当作NA处理。可以使用isnull方法来判断数据中是否存在NA值。例如,在Series中,可以使用string_data.isnull()来判断字符串数据中是否存在NA值。 另外,在处理重复值时,默认情况下,duplicates和drop_duplicates方法会保留第一个出现的值组合。如果想保留最后一个出现的值组合,可以传入take_last=True参数。例如,在一个DataFrame中,可以使用data.drop_duplicates(['k1','k2'],take_last=True)来删除重复值并保留最后一个出现的值组合。 综上所述,以上是关于Pythonpandas库进行数据预处理的一些基本操作和方法。可以根据具体需求使用相应的方法来进行数据清洗和处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [利用Python Pandas进行数据预处理-数据清洗](https://blog.csdn.net/YEN_CSDN/article/details/53445616)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值