数据分析前的准备工作包括:首先是要明确问题以及分析的方向,其次数据的收集,然后是数据的清洗,最后是数据的分析工作。整个过程最错综复杂的就是数据清洗工作,本次尝试着把之前遇到的数据清洗的一些步骤和方法做一个总结,并且随着以后的工作和学习不断完善。
1、数据预处理当我们导入一份数据后,我们需要对数据的大概有个了解。利用描述性统计可以很方便的对数据有个大致的了解,数据包括数值类型和非数值类型(一般是Object),通过对count max min mean std 等以及 唯一值 出现次数最多的(top),频率等信息的观察可以很好的为下面的步骤做铺垫。#数值类型
data.describe().T
#非数值类型
select_dtypes(include=[‘O’]).describe().T2.数据缺失值处理:python缺失值有3种:1)Python内置的None值2)在pandas中,将缺失值表示为NA,表示不可用not available。3)对于数值数据,pandas使用浮点值NaN(Not a Number)表示缺失数据。 后面出来数据,如果遇到错误:说什么float错误,那就是有缺失值,需要处理掉所以,缺失值有3种:None,NA,NaN那None和NaN有什么区别呢:None是Python的一种数据类型,NaN是浮点类型两个都用作空值(1)查看数据缺失值的常用方法:#如果你要检查每列缺失数据的数量,使用下列代码是最快的方法。
data.isnull().sum().sort_values(ascending=False)
#如果详细的查看每个缺失列的情况和比例:
missing=pd.concat([data.isnull().any(),data.count()],axis=1)
column=[‘是否缺失’,‘数量’]
missing=pd.DataFrame(list(missing.values),index=list(missing.index),columns=column)
max=missing[‘数量’].max()
missing[‘缺失数量’]=max-missing[‘数量’]
missing[‘缺失率’]=missing[‘缺失数量’]/max
miss=missing[missing[‘数量’] < max]
print(miss)(2)处理缺失值-删除#如果某个列缺失比较严重,比如缺失一半以上。我们可以将这些列删除
half_count=len(data)/2
data_new=data.dropna(thresh=half_count,axis=1)
不按照阈值删除
data.dropna(axis=0,how=‘any’,thresh=None,subset=None,inplace=False)
处理缺失值-填充1) 以业务知识或经验推测(默认值)填充缺失值2) 以同一指标的计算结果(均值、中位数、众数等)填充缺失值 3) 用相邻值填充缺失值4) 以不同指标的计算结果填充缺失值3.逻辑内容清洗(1)去除重复值 首先检查是否有重复值:#统计list或者series的不同值,返回的是唯一值的列表形式
data.name.unique()
统计DataFrame每列 或者Series的不同值个数, 返回的是一个数字。
data.nunique()
#如果检查某一列是否唯一的,返回bool类型;仅限用于列
data.name.is_unique
#DataFrame的duplicated方法返回一个布尔型Series,表示各行是否是重复行。仅限用于行
data.duplicated()接着删除重复值:#drop_duplicates默认是对所有的列进行操作,也可以基于某几列去操作。
data.drop_duplicates([‘k1’,‘k2’],keep=‘last’)
(2)异常点处理异常值我们通常也称为“离群点”。除了画图(画图其实并不常用,因为数据量多时不好画图,而且慢),还有很多其他方法:比较简单的就是在数据预处理的时候通过描述性统计观察,或者进行下面更加细致的处理。 1、3igma原理:3Sigma又称为拉依达准则,这种判别处理原理及方法仅局限于对正态或近似正态分布的样本数据处理,原则:数值分布在(μ-σ,μ+σ)中的概率为0.6827数值分布在(μ-2σ,μ+2σ)中的概率为0.9545数值分布在(μ-3σ,μ+3σ)中的概率为0.9973所以,数据在(μ-3σ,μ+3σ)的概率低于0.01,我们可以称这些数据为异常值。Python实现:1、依据历史数据计算出正常区间(μ-3σ,μ+3σ)2、判断目标数据是否有异常值#输出正区间
def ThreeSigmod(value):
#value是单维的历史数据
vg = np.mean(value)
std = np.std(value)
threshold_up = avg + 3std
threshold_down = avg -3std
return [float(threshold_down),float(threshold_up)]
#输出异常值
def function_ar(histroy,predict):
threshold = ThreeSigmod(histroy)
error = list(filter(lambda s:(s<threshold[0])|(s>threshold[1]),predict) return error
局限:1、要保证历史数据异常点较少(均值容易被异常点拉偏)2、只能检测单维数据3、需假定数据服从正态分布或近正态分布2 箱线图1、计算第一四分位数(Q1)及第三四分位数(Q3)2、计算IQR (IQR = Q3 - Q1)3、输出正常区间[Q1-1.5IQR,Q3+1.5IQRdef NumericOutlier(value):
#value是单维的历史数据
iqr = np.quantile(value,0.75) - np.quantile(value,0.25)
quan_down = np.quantile(value,0.25)-1.5iqr
quan_up = np.quantile(value,0.75)+1.5iqr
return [float(quan_down),float(quan_up)]
#输出异常值
def function_ar(histroy,predict):
threshold = ThreeSigmod(histroy)
error = list(filter(lambda s:(s<threshold[0])|(s>threshold[1]),predict)
return error
4 格式一致化:(1)调整数据类型#字符串转换为数值(整型)
DataDF[‘Quantity’] = DataDF[‘Quantity’].astype(‘int’)
#字符串转换为数值(浮点型)
DataDF[‘UnitPrice’] = DataDF[‘UnitPrice’].astype(‘float’)
#利用正则表达式只选择期限的数字
def get_term_num(term):
return int(re.findall(r’(\d\d)’, term)[0])
df[‘term_num’] = df[‘term’].apply(get_term_num)(2)日期和时间# 首先将issue_d转变为时间类型,然后在设置成“年份”
df[‘year’]=pd.to_datetime(df[‘issue_d’]).dt.year
#如果是分析月份
df[‘complete_date’] = pd.to_datetime(df[‘issue_d’])
group_dates = df.groupby(‘complete_date’, as_index=False).sum()
group_dates[‘issue_d’] = [month.to_period(‘M’) for month in group_dates[‘complete_date’]](3)大小写/去除空格DataDF[‘Description’]= DataDF[‘Description’].str.upper()
此外还有
str().
upper()
lower()
title()
lstrip()
strip()
DataDF[‘Description’]= DataDF[‘Description’].str.strip()(4)替代值replace 和 str.replacepd.replace(to_replace,value)str.replace(oldstr,newstr,num)
作者:王振群
链接:https://zhuanlan.zhihu.com/p/80210695
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。