Python—实训day9—使用pandas进行数据预处理

时间:2024-03-28 19:35:16

1合并数据

1.1堆叠合并数据

1.1.1横向堆叠(行对齐,左右拼接)

横向堆叠,即将两个表在X轴向拼接在一起,可以使用concat函数完成,concat函数的基本语法如下。

pandas.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, copy=True)

常用参数如下所示。

Python—实训day9—使用pandas进行数据预处理

Python—实训day9—使用pandas进行数据预处理

①当axis=1的时候,concat做行对齐,然后将不同列名称的两张或多张表合并。当两个表索引不完全一样时,可以使用join参数选择是内连接还是外连接。在内连接的情况下,仅仅返回索引重叠部分。在外连接的情况下,则显示索引的并集部分数据,不足的地方则使用空值填补。

②当两张表完全一样时,不论join参数取值是inner或者outer,结果都是将两个表完全按照X轴拼接起来。

Python—实训day9—使用pandas进行数据预处理

import pandas as pd

detail = pd.read_excel(r'F:\Desktop\meal_order_detail.xlsx')

detail.shape #(2779, 19)

info = pd.read_csv(r'F:\Desktop\meal_order_info.csv', encoding='gbk')

info.shape #(945, 21)

a = detail.iloc[:, :10]

a.shape #(2779, 10)

b = detail.iloc[:, 10:]

b.shape #(2779, 9)

#横向堆叠

c = pd.concat([a, b], axis=1)

c.shape #(2779, 19)

1.1.2纵向堆叠(列对齐,上下拼接)

(1)concat函数:

使用concat函数时,在默认情况下,即axis=0时,concat做列对齐,将不同行索引的两张或多张表纵向合并。在两张表的列名并不完全相同的情况下,可join参数取值为inner时,返回的仅仅是列名交集所代表的列,取值为outer时,返回的是两者列名的并集所代表的列,其原理示意如图。

不论join参数取值是inner或者outer,结果都是将两个表完全按照Y轴拼接起来。

Python—实训day9—使用pandas进行数据预处理

(2)append方法

append方法也可以用于纵向合并两张表。但是append方法实现纵向表堆叠有一个前提条件,那就是两张表的列名需要完全一致。append方法的基本语法如下:

pandas.DataFrame.append(self, other, ignore_index=False, verify_integrity=False)

常用参数如下所示。

Python—实训day9—使用pandas进行数据预处理

a = detail.iloc[:100, :]

a.shape #(100, 19)

b = detail.iloc[100:, :]

b.shape #(2679, 19)

#--concat函数

c = pd.concat([a, b], axis=0)

c.shape #(2779, 19)

#--append方法:两张表的列名需要完全一致

d = a.append(b)

d.shape #(2779, 19)

1.2主键合并数据

主键合并,即通过一个或多个键将两个数据集的行连接起来,类似于SQL中的JOIN。针对同一个主键存在两张包含不同字段的表,将其根据某几个字段一一对应拼接起来,结果集列数为两个元数据的列数和减去连接键的数量。

Python—实训day9—使用pandas进行数据预处理

和数据库的join一样,merge函数也有左连接(left)、右连接(right)、内连接(inner)和外连接(outer),但比起数据库SQL语言中的join和merge函数还有其自身独到之处,例如可以在合并过程中对数据集中的数据进行排序等。

pandas.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=True, indicator=False)

可根据merge函数中的参数说明,并按照需求修改相关参数,就可以多种方法实现主键合并。

Python—实训day9—使用pandas进行数据预处理

e = pd.merge(detail, info, on='emp_id')

e.shape #(7856, 39)

detail.shape #(2779, 19)

info.shape #(945, 21)

1.3重叠数据合并

数据分析和处理过程中若出现两份数据的内容几乎一致的情况,但是某些特征在其中一张表上是完整的,而在另外一张表上的数据则是缺失的时候,可以用combine_first方法进行重叠数据合并,其原理如下。

Python—实训day9—使用pandas进行数据预处理

combine_first的具体用法如下。

pandas.DataFrame.combine_first(other)

参数及其说明如下。

Python—实训day9—使用pandas进行数据预处理

import numpy as np

a = pd.DataFrame({'id':[1, np.nan, 3, np.nan, 5], 'cpu':[np.nan, 'i3', 'i5', np.nan, np.nan]})

b = pd.DataFrame({'id':[np.nan, 2, 3, np.nan, 5], 'cpu':['i7', 'i3', np.nan, 'i5', 'i3']})

a.combine_first(b)

2清洗数据

2.1检测与处理重复值

2.1.1记录重复

记录重复,即一个或者多个特征某几个记录的值完全相同

①方法一是利用列表(list)去重,自定义去重函数。

②方法二是利用集合(set)的元素是唯一的特性去重,如dish_set = set(dishes)

比较上述两种方法可以发现,方法一代码冗长。方法二代码简单了许多,但会导致数据的排列发生改变。

③pandas提供了一个名为drop_duplicates的去重方法。该方法只对DataFrame或者Series类型有效。这种方法不会改变数据原始排列,并且兼具代码简洁和运行稳定的特点。该方法不仅支持单一特征的数据去重,还能够依据DataFrame的其中一个或者几个特征进行去重操作。

pandas.DataFrame(Series).drop_duplicates(self, subset=None, keep='first', inplace=False)

Python—实训day9—使用pandas进行数据预处理

#--方法一:编写自定义函数

def delRep(data):

list1 = [] #用于存放无重复数据

for i in data:

if i not in list1:

list1.append(i)

return list1

list1 = delRep(detail['order_id'])

print('去重前的数据大小:', len(detail['order_id']))

print('去重后的数据大小:', len(list1))

#--方法二:利用集合去重(数据的顺序会发生改变)

set([1, 2, 2, 4, 3, 1])

set(detail['order_id'])

#--方法三:drop_duplicates方法去重

detail.drop_duplicates('order_id', inplace=True)

detail['order_id'].drop_duplicates()

2.1.2特征去重

结合相关的数学和统计学知识,去除连续型特征重复可以利用特征间的相似度将两个相似度为1的特征去除一个。在pandas中相似度的计算方法为corr,使用该方法计算相似度时,默认为“pearson”法 ,可以通过“method”参数调节,目前还支持“spearman”法和“kendall”法。

但是通过相似度矩阵去重存在一个弊端,该方法只能对数值型重复特征去重,类别型特征之间无法通过计算相似系数来衡量相似度。

除了使用相似度矩阵进行特征去重之外,可以通过DataFrame.equals的方法进行特征去重。

#--第一种方法:corr方法判断特征是否去重

detail[['counts', 'amounts']].corr()

detail[['counts', 'amounts', 'dishes_name']].corr() #只能对数值型重复特征去重,类别型特征之间无法通过计算相似系数来衡量相似度。

#--第二种方法:equals方法判断特征是否去重

detail['counts'].equals(detail['amounts'])

2.2检测与处理缺失值

2.2.1检测缺失值

数据中的某个或某些特征的值是不完整的,这些值称为缺失值。

pandas提供了识别缺失值的方法isnull以及识别非缺失值的方法notnull,这两种方法在使用时返回的都是布尔值True和False。

结合sum函数和isnull、notnull函数,可以检测数据中缺失值的分布以及数据中一共含有多少缺失值。

isnull和notnull之间结果正好相反,因此使用其中任意一个都可以判断出数据中缺失值的位置。

detail.isnull() #布尔值

detail.isnull().sum() #统计每一列的缺失值个数

detail.isnull().sum().sum() #统计出整个数据集的缺失值个数

2.2.2删除法

删除法分为删除观测记录和删除特征两种,它属于利用减少样本量来换取信息完整度的一种方法,是一种最简单的缺失值处理方法。

pandas中提供了简便的删除缺失值的方法dropna,该方法既可以删除观测记录,亦可以删除特征。

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

常用参数及其说明如下。

Python—实训day9—使用pandas进行数据预处理

detail.dropna(axis=1, how='all', inplace=True)

#--------------------------------

#----

#----

#----2.2.3替换法

a = pd.DataFrame({'id':[1, np.nan, 3, np.nan, 5], 'cpu':[np.nan, 'i3', 'i5', 'i3', np.nan]})

#--数值型数据

id_mean = a['id'].mean()

a['id'].fillna(id_mean) #均值填补缺失值

#--类别型数据:选择使用众数来替换缺失值

zhongshu = a['cpu'].value_counts().index[0]

a['cpu'].fillna(zhongshu)

#----2.2.4插值法(插值是一种通过已知的、离散的数据点,在范围内推求新数据点的过程或方法)

#拉格朗日插值

from scipy.interpolate import lagrange

x = np.array([1, 2, 4, 6, 9])

y = np.array([2, 4, 6, 9, 10])

model = lagrange(x, y)

model([5])

#------------2.3检测与处理异常值--------------------

#----2.3.1 3σ原则

u = detail['counts'].mean() #均值

o = detail['counts'].std() #标准差

detail['counts'].apply(lambda x:x < u-3*o or x > u+3*o)

#----2.3.2箱线图分析

import matplotlib.pyplot as plt

a = plt.boxplot(detail['counts'])

plt.show()

a['fliers'][0].get_ydata()

#==================3标准化数据

#------------3.1离差标准化数据--------------------

def MinMaxScaler(data) :

new_data = (data - data.min())/(data.max()-data.min())

return new_data

MinMaxScaler(detail['amounts'])

#------------3.2标准差标准化--------------------

def StandarScaler(data):

new_data = (data - data.mean())/data.std()

return new_data

StandarScaler(detail['amounts'])

#------------3.3小数定标标准化数据--------------------

import numpy as np

def DecimalScaler(data):

new_data = data/10**np.ceil(np.log10(data.abs().max())) #ceil表取整数

return new_data

DecimalScaler(detail['amounts'])

#==================4转换数据

#------------4.1哑变量处理类别数据--------------------

pd.get_dummies(detail['dishes_name'])

pd.get_dummies(detail)

#------------4.2离散化连续型数据--------------------

#----4.2.1等宽离散化

detail['amounts'] = pd.cut(detail['amounts'], 5)

#----4.2.2等频离散化

detail = pd.read_excel(r'F:\Desktop\meal_order_detail.xlsx')

def SameRateCue(data, k):

w = data.quantile(np.arange(0, 1+1/k, 1/k))

new_data = pd.cut(data, w)

return new_data

SameRateCue(detail['amounts'], 5)

SameRateCue(detail['amounts'], 5).value_counts()

#---4.2.3k-means聚类离散化

def KmeansCut(data,k):

from sklearn.cluster import KMeans #pip install scikit-learn -i https://mirrors.aliyun.com/pypi/simple

#建立模型

kmodel=KMeans(n_clusters=k, n_jobs=4) #n_jobs是并行数,一般等于CPU数较好

#训练模型

kmodel.fit(np.array(data).reshape(len(data), 1)) #转换成一列

#输出聚类中心并排序

c=pd.DataFrame(kmodel.cluster_centers_).sort_values(0) #把聚类中心作成一个表格并排序

#相邻两项求中点,作为边界点

w=c.rolling(2).mean().iloc[1:] #不要第0个,所以是从第1个开始

#把首末边界点加上

w=[0]+list(w[0])+[data.max()] #相当于加了个0和最大值

data=pd.cut(data,w)

return data

KmeansCut(detail['amounts'],5).value_counts()