数据清洗是数据分析中很重要的一步,好比蔬菜水果要洗过之后再吃,不然容易拉肚子;
本文目的是持续搜集总结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σ: 正态分布或近似正态分布
(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.丧心病狂无定向型
不同情况想办法!!!
来源:CSDN
作者:Drivercsdn
链接:https://blog.csdn.net/DriverCSDN/article/details/103762413