Python|使用 Python 进行数据清洗的完整指南( 二 )


)
   IQR = Q3 - Q1
   lower_range = Q1 - (1.5 * IQR)
   upper_range = Q3 + (1.5 * IQR)
   return lower_rangeupper_range
 
for col in columns:  
   lowerboundupperbound = lower_upper_range(df[col
)
   df[col
=np.clip(df[col
a_min=lowerbounda_max=upperbound)
数据不一致异常值问题是关于数字特征的 , 现在让我们看看字符类型(分类)特征 。数据不一致意味着列的唯一类具有不同的表示形式 。例如在性别栏中 , 既有m/f , 又有male/female 。 在这种情况下 , 就会有4个类 , 但实际上有两类 。
这种问题目前没有自动处理的办法 , 所以需要手动进行分析 。pandas 的unique函数就是为了这个分析准备的 , 下面看一个汽车品牌的例子:
df['CarName'
= df['CarName'
.str.split().str[0

print(df['CarName'
.unique())

maxda-mazda Nissan-nissan porcshce-porsche toyouta-toyota等都可以进行合并 。
df.loc[df['CarName'
== 'maxda' 'CarName'
= 'mazda'
df.loc[df['CarName'
== 'Nissan' 'CarName'
= 'nissan'
df.loc[df['CarName'
== 'porcshce' 'CarName'
= 'porsche'
df.loc[df['CarName'
== 'toyouta' 'CarName'
= 'toyota'
df.loc[df['CarName'
== 'vokswagen' 'CarName'
= 'volkswagen'
df.loc[df['CarName'
== 'vw' 'CarName'
= 'volkswagen'
无效数据无效的数据表示在逻辑上根本不正确的值 。例如 ,

  • 某人的年龄是 560;
  • 某个操作花费了 -8 小时;
  • 一个人的身高是1200 cm等;
对于数值列 , pandas的 describe 函数可用于识别此类错误:
df.describe()

无效数据的产生原因可能有两种:
1、数据收集错误:例如在输入时没有进行范围的判断 , 在输入身高时错误的输入了1799cm 而不是 179cm , 但是程序没有对数据的范围进行判断 。
2、数据操作错误
数据集的某些列可能通过了一些函数的处理 。例如 , 一个函数根据生日计算年龄 , 但是这个函数出现了BUG导致输出不正确 。
以上两种随机错误都可以被视为空值并与其他 NA 一起估算 。
重复数据当数据集中有相同的行时就会产生重复数据问题 。这可能是由于数据组合错误(来自多个来源的同一行) , 或者重复的操作(用户可能会提交他或她的答案两次)等引起的 。处理该问题的理想方法是删除复制行 。
可以使用 pandas duplicated 函数查看重复的数据:
df.loc[df.duplicated()

在识别出重复的数据后可以使用pandas 的 drop_duplicate 函数将其删除:
df.drop_duplicates()
数据泄漏问题在构建模型之前 , 数据集被分成训练集和测试集 。测试集是看不见的数据用于评估模型性能 。如果在数据清洗或数据预处理步骤中模型以某种方式“看到”了测试集 , 这个就被称做数据泄漏(data leakage) 。所以应该在清洗和预处理步骤之前拆分数据:

以选择缺失值插补为例 。 数值列中有 NA , 采用均值法估算 。 在 split 前完成时 , 使用整个数据集的均值 , 但如果在 split 后完成 , 则使用分别训练和测试的均值 。
第一种情况的问题是 , 测试集中的推算值将与训练集相关 , 因为平均值是整个数据集的 。 所以当模型用训练集构建时 , 它也会“看到”测试集 。 但是我们拆分的目标是保持测试集完全独立 , 并像使用新数据一样使用它来进行性能评估 。 所以在操作之前必须拆分数据集 。
虽然训练集和测试集分别处理效率不高(因为相同的操作需要进行2次) , 但它可能是正确的 。 因为数据泄露问题非常重要 , 为了解决代码重复编写的问题 , 可以使用sklearn 库的pipeline 。 简单地说 , pipeline就是将数据作为输入发送到的所有操作步骤的组合 , 这样我们只要设定好操作 , 无论是训练集还是测试集 , 都可以使用相同的步骤进行处理 , 减少的代码开发的同时还可以减少出错的概率 。