数据分析之清洗和整理
程序员文章站
2022-04-28 23:54:06
...
数据清洗
- 脏数据或数据不正确,比如 ‘0’ 代表真实的 0,还是代表缺失;错误数据,Age = -2003
- 数据不一致,比如收入单位是万元,利润单位是元,或者一个单位是美元,一个是人民币
- 数据重复
- 缺失值
- 离群值
利用图形可以直观快速地对数据进行初步分析,直方图、饼图、条形图、折线图、散点图等
import pandas as pd
import os
import numpy as np
os.chdir(r"D:\pydata")
camp = pd.read_csv('teleco_camp_orig.csv')
camp.head()
Out[7]:
ID Suc_flag ARPU ... AvgARPU AvgHomeValue AvgIncome
0 12 1 50.0 ... 49.894904 33400 39460
1 53 0 NaN ... 48.574742 37600 33545
2 67 1 25.0 ... 49.272646 100400 42091
3 71 1 80.0 ... 47.334953 39900 39313
4 142 1 15.0 ... 47.827404 47500 0
import matplotlib.pyplot as plt
plt.hist(camp['AvgIncome'], bins=20, normed=True)#查看分布情况
平均收入为 0,应该是缺失值。发现错误值只能通过描述性统计的方法,逐一核实每个变量是否有问题,比如 ‘0’ 代表真实的0,
还是代表缺失?
处理错误值
修正:补充正确信息;对照其他信息源;视为空值
删除:删除记录;删除字段
#这里的0值应该是缺失值
camp['AvgIncome']=camp['AvgIncome'].replace({0: np.NaN})
#像这种外部获取的数据要比较小心,经常出现意义不清晰或这错误值。AvgHomeValue也有这种情况
plt.hist(camp['AvgIncome'], bins=20, normed=True,range=(camp.AvgIncome.min(),camp.AvgIncome.max()))#由于数据中存在缺失值,需要指定绘图的值域
camp['AvgIncome'].describe(include='all')
Out[11]:
count 7329.000000
mean 53513.457361
std 19805.168339
min 2499.000000
25% 40389.000000
50% 48699.000000
75% 62385.000000
max 200001.000000
发现缺失值
处理原则
首选基于业务的填补方法,其次根据单变量分析进行填补。
多重插补进行所有变量统一填补的方法只有在粗略清洗时才会使用。
缺失值少于20%
- 连续变量使用均值或中位数填补
- 分类变量不需要填补,单算一类即可,或者用众数填补
缺失值在20%-80%
- 填补方法同上
- 另外每个有缺失值的变量生成一个指示哑变量(如 0,1等),参与后续的建模
缺失值在大于80%
- 每个有缺失值的变量生成一个指示哑变量,参与后续的建模,原始变量不使用。
# skipna=True 把缺失值去掉计算均值
vmean = camp['Age'].mean(axis=0, skipna=True)
camp['Age_empflag'] = camp['Age'].isnull()
camp['Age']= camp['Age'].fillna(vmean)
camp['Age'].describe()
Out[12]:
count 9686.000000
mean 49.567386
std 6.060585
min 16.000000
25% 47.000000
50% 49.567386
75% 54.000000
max 60.000000
Name: Age, dtype: float64
横着删缺失值过多的,然后纵着补缺
噪声值处理
单变量离群值发现
极端值
- 设置标准,如:5倍标准差之外的数据
- 极值有时意味着错误,应重新理解数据,例如:特殊用户的超大额消费
离群值
- 平均值法:平均值 ± n 倍标准差之外的数据;建议的临界值:|SR| > 2 (两倍标准差),用于观察值较少的数据集,|SR| > 3 (三倍标准差),用于观察值较多的数据集
- 四分位数法:IQR = Q3 – Q1;Q1 – 1.5 * IQR ~ Q3 + 1.5 * IQR , 更适用于对称分布的数据
处理方法
1. 直接删除
2. 盖帽法
# - 盖帽法,小于 floor 的用 floor 代替, 大于 root 的,用 root代替
def blk(floor, root): # 'blk' will return a function
def f(x):
if x < floor:
x = floor
elif x > root:
x = root
return x
return f
q1 = camp['Age'].quantile(0.01) # 计算百分位数
q99 = camp['Age'].quantile(0.99)
blk_tot = blk(floor=q1, root=q99) # 'blk_tot' is a function
camp['Age']= camp['Age'].map(blk_tot)
camp['Age'].describe()
Out[13]:
count 9686.000000
mean 49.624685
std 5.835803
min 31.000000
25% 47.000000
50% 49.567386
75% 54.000000
max 60.000000
Name: Age, dtype: float64
3. 分箱法
# - 分箱(等深,等宽)
# - 分箱法——等宽分箱
# In[ ]:
camp['Age_group1'] = pd.qcut( camp['Age'], 4) # 这里以age_oldest_tr字段等宽分为4段
camp.Age_group1.head()
Out[14]:
0 (54.0, 60.0]
1 (54.0, 60.0]
2 (54.0, 60.0]
3 (49.567, 54.0]
4 (47.0, 49.567]
# - 分箱法——等深分箱
# In[ ]:
camp['Age_group2'] = pd.cut( camp['Age'], 4) # 这里以age_oldest_tr字段等宽分为4段
camp.Age_group2.head()
Out[15]:
0 (52.75, 60.0]
1 (52.75, 60.0]
2 (52.75, 60.0]
3 (45.5, 52.75]
4 (45.5, 52.75]
最后保存数据
camp.to_csv('tele_camp_ok.csv')
上一篇: Mybatis 01 环境搭建和基本使用
下一篇: 小白学数据分析——数据清洗