python数据清洗记录(持续更新)

谁说胖子不能爱 提交于 2020-01-19 04:27:52

数据清洗是数据分析中很重要的一步,好比蔬菜水果要洗过之后再吃,不然容易拉肚子;
本文目的是持续搜集总结python对各种数据进行清洗的方法,之后遇到忘记的在这里Ctrl+F就找得到;
文中有提供简单的案例,看到的同学可以复制黏贴操作一下;

数据清洗

数值类

1缺失值
1.1缺失值的类型

NaN – not a number – 对于数来说,非数字
None – 对于object来说,没东西
NaT – not a time --对于时间来说,非时间

test11 = pd.DataFrame({'num':[1,2,np.nan,4],
                       'obj':['a',None,'c','d'],
                       'time':pd.to_datetime(['2022-01-01','2022-01-02','2022-01-03',np.nan])})

在这里插入图片描述

1.2缺失值的探索分析
#isnull(),探索上述缺失值类型,返回bool型
test11.isnull() 

#对布尔型的dataframe进行求和聚合查看数量
test11.isnull().sum()

#计算缺失值占比
test11.isnull().sum()/test11.isnull().count() 

#定位空值在哪些行
test11[~test11.index.isin(test11.dropna().index)] 
1.3缺失值的处理

应先考虑缺失值代表什么,是否有意义,再考虑怎么处理,基本的处理有三类:
(1)不处理
(2)删除

test13 = test11
test13.dropna(how = 'any',subset = ['num','obj'])

dropna()参数:可根据需求实现较灵活的操作
axis: 0是行,1是列,
how: 删除形式,'any'有空值就删掉,'all'全部是空值才删掉
thresh:	int,只删掉有n个及以上空值的行
subset: 只对某子集生效,你选定哪些行/列
inplace: 是否替代原数据

(3)插值
#特殊值插值: 均值,分位数,中位数,特定值等

test13.fillna(value = {'num':test13['num'].mean(),'obj':'hello'})

fillna()参数:
value(): 你要插入的值,可以用dict,series等形式
method: 插值方式,默认是无,'backfill'用后一个数据插值,'ffill'用前一个插值等
axis: 指定行列
limit: 指定只插n个值

#: 考虑数据有联系,可用拉格朗日插值,样条插值等方法

from scipy.interpolate import lagrange
from scipy.interpolate import interp1d

#根据数据生成插值函数
x = [1,2,3,4,5,7]
y = [2,1,3,0.5,2,1]
a = interp1d(x,y,kind = 'cubic')
b = lagrange(x,y)

#看看插值函数是怎样的(这里用ploty画图)
x1 = np.linspace(1,7,num = 100)
y_cub = a(x1)
y_lag = b(x1)

在这里插入图片描述

1.4归纳产生原因

(1)分析为什么不能获取
(2)不能获取的数据,限制数据的输入格式

1.5非常规类型缺失值
#不同数据类型的缺失值
test15 = pd.DataFrame({'num':[1,2,'没有',4]})
test15[test15['num'].apply(lambda x :isinstance(x,int))]

在这里插入图片描述在这里插入图片描述

2异常值
2.1数据限制外的异常值

通过比较运算及集合运算等就可以去除

2.2数据分布异常值

(1)3σ: 正态分布或近似正态分布
在正态分布中,均值±3σ的范围内包含了99%以上的数据,如果出现3σ外的数据,表示该数据出现的概率很小,划分为异常值
(2)IQR:箱型图,IQR = Q3-Q1
箱体图是以计数来划分数据的,因此它不像方差均值那样会收到极端值的影响,一般情况下划分异常值的界限是>Q3+1.5IQR, <Q1-1.5IQR。
在这里插入图片描述

文本类

1.object类型 – 可枚举的数据(正确可枚举,错误可枚举)
fruit = ['apple','orange','kiwi','kumquat']
test11 = pd.DataFrame({'fruit':['apple','orange','kiwi','penpineapple']})
test12 = pd.DataFrame({'fruit':['apple','orange','kiwi','nothing']})

test11[~test11['fruit'].isin(fruit)]   #penpineapple
test12[~test12['fruit'].isin(fruit)]   #nothing
2.有格式的混合型

(1) 符号+数字

test21 = pd.Series({'price':['$1.10','$22','¥0.3']})

 [in]  re.sub('[\$¥]','','$$¥33.1')
[out]  '33.1'

 [in]  re.findall('[\d+\.]+','$$¥33.11')
[out]  ['33.11']

 [in]  test21['price'].map(lambda x : re.sub('[\$¥]','',x))
[out]  0   1.10
       1   22
       2   0.3

re.sub()参数:匹配替换字符串
pattern: 正则表达式的匹配模式
repl: 替换成什么 
string: 字符串对象

re.findall()参数: 查找所有匹配字符,返回列表类型

(2)固定格式

test22 = pd.DataFrame({'a':['差不多/先生-差不多,要;飞升','猎魔/人-猎,到;山顶洞人']})

test22.assign(b=test22['a'].map(lambda x :re.split('/|-|,|;',x)[0]),
             c=test22['a'].map(lambda x :re.split('/|-|,|;',x)[1]),
             d=test22['a'].map(lambda x :re.split('/|-|,|;',x)[2]),
             e=test22['a'].map(lambda x :re.split('/|-|,|;',x)[3]),
             f=test22['a'].map(lambda x :re.split('/|-|,|;',x)[4]))

在这里插入图片描述

3.丧心病狂无定向型

不同情况想办法!!!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!