Python代码实操:详解数据清洗

本文示例中,主要用了几个知识点:


  • 通过 pd.DataFrame 新建数据框。
  • 通过 df.iloc[] 来选择特定的列或对象。
  • 使用Pandas的 isnull() 判断值是否为空。
  • 使用 all() 和 any() 判断每列是否包含至少1个为True或全部为True的情况。
  • 使用Pandas的 dropna() 直接删除缺失值。
  • 使用 sklearn.preprocessing 中的 Imputer 方法对缺失值进行填充和替换,支持3种填充方法
  • 使用Pandas的 fillna 填充缺失值,支持更多自定义的值和常用预定义方法
  • 通过 copy() 获得一个对象副本,常用于原始对象和复制对象同时进行操作的场景。
  • 通过 for 循环遍历可迭代的列表值。
  • 自定义代码实现了 Z-score 计算公式。
  • 通过Pandas的 duplicated() 判断重复数据记录。
  • 通过Pandas的 drop_duplicates() 删除数据记录,可指定特定列或全部。



01 缺失值处理


在缺失值的处理上,主要配合使用 sklearn.preprocessing 中的Imputer类、Pandas和Numpy。其中由于Pandas对于数据探索、分析和探查的支持较为良好,因此围绕Pandas的缺失值处理较为常用。


1. 导入库


代码示例中用到Pandas、Numpy和sklearn。


import pandas as pd               # 导入Pandas库
import numpy as np               # 导入numpy库
from sklearn.preprocessing import Imputer     # 导入sklearn.preprocessing中的Imputer库


2. 生成缺失数据


生成缺失数据
df = pd.DataFrame(np.random.randn(6, 4), columns=['col1', 'col2', 'col3', 'col4'])                      # 生成一份数据
df.iloc[1:2, 1] = np.nan            # 增加缺失值
df.iloc[4, 3] = np.nan               # 增加缺失值
print(df)


通过Pandas生成一个6行4列,列名分别为'col1'、'col2'、'col3'、'col4'的数据框。同时,数据框中增加两个缺失值数据。


除了示例中直接通过pd.DataFrame来直接创建数据框外,还可以使用数据框对象的 df.from_records、df.from_dict、df.from_items 来从元组记录、字典和键值对对象创建数据框,或使用pandas.read_csv、pandas.read_table、pandas.read_clipboard 等方法读取文件或剪贴板创建数据框。该代码段执行后返回了定义含有缺失值的数据框,结果如下:


       col1      col2      col3      col4
0 -0.112415 -0.768180 -0.084859  0.296691
1 -1.777315       NaN -0.166615 -0.628756
2 -0.629461  1.892790 -1.850006  0.157567
3  0.544860 -1.230804  0.836615 -0.945712
4  0.703394 -0.764552 -1.214379       NaN
5  1.928313 -1.376593 -1.557721  0.289643


提示:由于生成的数据是随机产生的,因此读者的实际结果可能与上述结果不一致。


3. 判断缺失值


# 查看哪些值缺失
nan_all = df.isnull()      # 获得所有数据框中的N值
print(nan_all)          # 打印输出
# 查看哪些列缺失
nan_col1 = df.isnull().any()    # 获得含有NA的列
nan_col2 = df.isnull().all()    # 获得全部为NA的列
print(nan_col1)              # 打印输出
print(nan_col2)              # 打印输出


通过 df.null() 方法找到所有数据框中的缺失值(认缺失值是 NaN 格式),然后使用 any() 或 all() 方法来查找含有至少1个或全部缺失值的列,其中 any() 方法用来返回指定轴中的任何元素为 True,而 all() 方法用来返回指定轴的所有元素都为 True。该代码段执行后返回如下结果。


判断元素是否是缺失值(第2行第2列和第5行第4列):


   col1   col2   col3   col4
0  False  False  False  False
1  False   True  False  False
2  False  False  False  False
3  False  False  False  False
4  False  False  False   True
5  False  False  False  False


列出至少有一个元素含有缺失值的列(该示例中为col2和col4):


col1    False
col2     True
col3    False
col4     True
dtype: bool


列出全部元素含有缺失值的列(该示例中没有):


col1    False
col2    False
col3    False
col4    False
dtype: bool


4. 丢弃缺失值


df2 = df.dropna()  # 直接丢弃含有NA的行记录
print(df2)  # 打印输出


通过Pandas认的 dropna() 方法丢弃缺失值,返回无缺失值的数据记录。该代码段执行后返回如下结果(第2行、第5行数据记录被删除):


       col1      col2      col3      col4
0 -0.112415 -0.768180 -0.084859  0.296691
2 -0.629461  1.892790 -1.850006  0.157567
3  0.544860 -1.230804  0.836615 -0.945712
5  1.928313 -1.376593 -1.557721  0.289643


5. 通过sklearn的数据预处理方法对缺失值进行处理


nan_model = Imputer(missing_values='NaN', strategy='mean', axis=0)  # 建立替换规则:将值为NaN的缺失值以均值做替换
nan_result = nan_model.fit_transform(df)  # 应用模型规则
print(nan_result)  # 打印输出


首先通过 Imputer 方法创建一个预处理对象,其中 missing_values 为认缺失值的字符串,认为 NaN;示例中选择缺失值替换方法是均值(认),还可以选择使用中位数和众数进行替换,即 strategy 值设置为 median 或 most_frequent;后面的参数 axis 用来设置输入的轴,认值为0,即使用列做计算逻辑。


然后使用预处理对象的 fit_transform 方法对 df(数据框对象)进行处理,该方法是将 fit 和 transform 组合起来使用。代码执行后返回如下结果:


[[-0.11241503 -0.76818022 -0.08485904  0.29669147]
 [-1.77731513 -0.44946793 -0.16661458 -0.62875601]
 [-0.62946127  1.89278959 -1.85000643  0.15756702]
 [ 0.54486026 -1.23080434  0.836615   -0.9457117 ]
 [ 0.70339369 -0.76455205 -1.21437918 -0.16611331]
 [ 1.92831315 -1.37659263 -1.55772092  0.28964265]]


代码中的第2行第2列和第5行第4列分别被各自列的均值替换。为了验证,我们手动计算一下各自列的均值,通过使用 df['col2'].mean() 和 df['col4'].mean() 分别获得这两列的均值为-0.4494679289032068和-0.16611331259664791,与sklearn返回的结果一致。


6. 使用Pandas做缺失值处理


nan_result_pd1 = df.fillna(method='backfill')          # 用后面的值替换缺失值
nan_result_pd2 = df.fillna(method='bfill', limit=1)      # 用后面的值替代缺失值,限制每列只能替代一个缺失值
nan_result_pd3 = df.fillna(method='pad')          # 用前面的值替换缺失值
nan_result_pd4 = df.fillna(0)                  # 用0替换缺失值
nan_result_pd5 = df.fillna({'col2': 1.1, 'col4': 1.2})    # 用不同值替换不同列的缺失值
nan_result_pd6 = df.fillna(df.mean()['col2':'col4'])    # 用各自列的平均数替换缺失值
# 打印输出
print(nan_result_pd1)                      # 打印输出
print(nan_result_pd2)                      # 打印输出
print(nan_result_pd3)                      # 打印输出
print(nan_result_pd4)                      # 打印输出
print(nan_result_pd5)                     # 打印输出
print(nan_result_pd6)                      # 打印输出


Pandas对缺失值的处理方法是 df.fillna(),该方法中最主要的两个参数是value 和 method。前者通过固定(或手动指定)的值替换缺失值,后者使用Pandas提供的方法替换缺失值。以下是 method 支持方法


  • pad 和 ffill:使用前面的值替换缺失值,示例中 nan_result_pd3 使用了 pad方法
  • backfill 和 bfill:使用后面的值替换缺失值,示例中 nan_result_pd1和 nan_result_pd2 使用了该方法
  • None:无。


在示例中, nan_result_pd4、nan_result_pd5、nan_result_pd6 分别使用0、不同的值、平均数替换缺失值。需要注意的是,如果要使用不同具体值替换,需要使用 scalar、dict、Series 或 DataFrame 的格式定义。


上述代码执行后返回如下结果。


用后面的值(method='backfill')替换缺失值:


       col1      col2      col3      col4
0 -0.112415 -0.768180 -0.084859  0.296691
1 -1.777315  1.892790 -0.166615 -0.628756
2 -0.629461  1.892790 -1.850006  0.157567
3  0.544860 -1.230804  0.836615 -0.945712
4  0.703394 -0.764552 -1.214379  0.289643
5  1.928313 -1.376593 -1.557721  0.289643


用后面的值(method='bfill', limit = 1)替换缺失值:


       col1      col2      col3      col4
0 -0.112415 -0.768180 -0.084859  0.296691
1 -1.777315  1.892790 -0.166615 -0.628756
2 -0.629461  1.892790 -1.850006  0.157567
3  0.544860 -1.230804  0.836615 -0.945712
4  0.703394 -0.764552 -1.214379  0.289643
5  1.928313 -1.376593 -1.557721  0.289643


用前面的值替换缺失值(method='pad'):


       col1      col2      col3      col4
0 -0.112415 -0.768180 -0.084859  0.296691
1 -1.777315 -0.768180 -0.166615 -0.628756
2 -0.629461  1.892790 -1.850006  0.157567
3  0.544860 -1.230804  0.836615 -0.945712
4  0.703394 -0.764552 -1.214379 -0.945712
5  1.928313 -1.376593 -1.557721  0.289643


用0替换缺失值:


       col1      col2      col3      col4
0 -0.112415 -0.768180 -0.084859  0.296691
1 -1.777315  0.000000 -0.166615 -0.628756
2 -0.629461  1.892790 -1.850006  0.157567
3  0.544860 -1.230804  0.836615 -0.945712
4  0.703394 -0.764552 -1.214379  0.000000
5  1.928313 -1.376593 -1.557721  0.289643


手动指定两个缺失值分布为1.1和1.2:


       col1      col2      col3      col4
0 -0.112415 -0.768180 -0.084859  0.296691
1 -1.777315  1.100000 -0.166615 -0.628756
2 -0.629461  1.892790 -1.850006  0.157567
3  0.544860 -1.230804  0.836615 -0.945712
4  0.703394 -0.764552 -1.214379  1.200000
5  1.928313 -1.376593 -1.557721  0.289643


用平均数代替,选择各自列的均值替换缺失值:


       col1      col2      col3      col4
0 -0.112415 -0.768180 -0.084859  0.296691
1 -1.777315 -0.449468 -0.166615 -0.628756
2 -0.629461  1.892790 -1.850006  0.157567
3  0.544860 -1.230804  0.836615 -0.945712
4  0.703394 -0.764552 -1.214379 -0.166113
5  1.928313 -1.376593 -1.557721  0.289643


以上示例中,直接指定 method 的方法适用于大多数情况,较为简单直接;但使用value 的方法则更为灵活,原因是可以通过函数的形式将缺失值的处理规则写好,然后直接赋值即可。限于篇幅,不对所有方法做展开讲解。


另外,如果是直接替换为特定值的应用,也可以考虑使用Pandas的 replace 功能。本示例的 df (原始数据框)可直接使用 df.replace(np.nan,0),这种用法更加简单粗暴,但也能达到效果。当然,replace的出现是为了解决各种替换应用的,缺失值只是其中的一种应用而已。


上述过程中,主要需要考虑的关键点是缺失值的替换策略,可指定多种方法替换缺失值,具体根据实际需求而定,但大多数情况下均值、众数和中位数的方法较为常用。如果场景固定,也可以使用特定值(例如0)替换。


在使用不同的缺失值策略时,需要注意以下几个问题:


  1. 缺失值的处理的前提是已经可以正确识别所有缺失值字段,关于识别的问题在使用Pandas读取数据时可通过设置 na_values 的值指定。但是如果数据已经读取完毕并且不希望再重新读取,那可以使用Pandas的 replace 功能将指定的字符串(或列表)替换为 NaN。更有效的是,如果数据中的缺失值太多而无法通过列表形式穷举时,replace 还支持正则表达式的写法。
  2. 当列中的数据全部为空值时,任何替换方法都将失效,任何基于中位数、众数和均值的策略都将失效。除了可以使用固定值替换外(这种情况下即使替换了该特征也没有实际参与模型的价值),最合理的方式是先将全部为缺失值的列删除,然后再做其他处理。
  3. 当列中含有极大值或极小值的 inf 或 -inf 时,会使得 mean() 这种方法失效,因为这种情况下将无法计算出均值。应对思路是使用 median 中位数做兜底策略,只要列中有数据,就一定会有中位数。



02 异常值处理


有关异常值的确定有很多规则和方法,这里使用Z标准化得到的阈值作为判断标准:当标准化后的得分超过阈值则为异常。完整代码如下。


示例代码分为3个部分。


1. 导入本例需要的Pandas库


import pandas as pd  # 导入Pandas库


2. 生成异常数据


df = pd.DataFrame({'col1': [1, 120, 3, 5, 2, 12, 13],
                   'col2': [12, 17, 31, 53, 22, 32, 43]})
print(df)  # 打印输出


直接通过DataFrame创建一个7行2列的数据框,打印输出结果如下:


   col1  col2
0     1    12
1   120    17
2     3    31
3     5    53
4     2    22
5    12    32
6    13    43


3. 为通过Z-score方法判断异常值


df_zscore = df.copy()                  # 复制一个用来存储Z-score得分的数据框
cols = df.columns                  # 获得数据框的列名
for col in cols:                      # 循环读取每列
    df_col = df[col]                  # 得到每列的值
    z_score = (df_col - df_col.mean()) / df_col.std()  # 计算每列的Z-score得分
    df_zscore[col] = z_score.abs() > 2.2        # 判断Z-score得分是否大于2.2,如果是则为True,否则为False
print(df_zscore)                      # 打印输出


本过程中,先通过 df.copy() 复制一个原始数据框的副本,用来存储Z-score标准化后的得分,再通过 df.columns 获得原始数据框的列名,接着通过循环判断每一列中的异常值。在判断逻辑中,对每一列的数据进行使用自定义方法做Z-score值标准化得分计算,然后与阈值2.2做比较,如果大于阈值则为异常。本段代码返回结果如下:


    col1   col2
0  False  False
1   True  False
2  False  False
3  False  False
4  False  False
5  False  False
6  False  False


在本示例方法中,阈值的设定是确定异常与否的关键,通常当阈值大于2.2时,就是相对异常的表现值。


4. 删除带有异常值所在的记录行


df_drop_outlier = df[df_zscore['col1'] == False]
print(df_drop_outlier)


本段代码里我们直接使用了Pandas的选择功能,即只保留在 df_zscore 中异常列(col1)为 False 的列。完成后在输出的结果中可以看到,删除了 index 值为1的数据行。


   col1  col2
0     1    12
2     3    31
3     5    53
4     2    22
5    12    32
6    13    43


上述过程中,主要需要考虑的关键点是:如何判断异常值。


对于有固定业务规则的可直接套用业务规则,而对于没有固定业务规则的,可以采用常见的数学模型进行判断:


  • 基于概率分布的模型(例如正态分布的标准差范围)
  • 基于聚类的方法(例如KMeans)
  • 基于密度的方法(例如LOF)
  • 基于分类方法(例如KNN)
  • 基于统计方法(例如分位数法)等。


异常值的定义带有较强的主观判断色彩,具体需要根据实际情况选择。



03 重复值处理


有关重复值的处理代码分为4个部分。


1. 导入用到的Pandas库


import pandas as pd  # 导入Pandas库


2. 生成重复数据


data1, data2, data3, data4 = ['a', 3], ['b', 2], ['a', 3], ['c', 2]
df = pd.DataFrame([data1, data2, data3, data4], columns=['col1', 'col2'])
print(df)


代码中,我们在一列中直接给4个对象赋值,也可以拆分为4行分别赋值。该数据是一个4行2列数据框,数据结果如下:


  col1  col2
0    a     3
1    b     2
2    a     3
3    c     2


3. 判断重复数据


isDuplicated = df.duplicated()    # 判断重复数据记录
print(isDuplicated)          # 打印输出


判断数据记录是否为重复值,返回每条数据记录是否重复结果,取值为 True 或False。判断方法为 df.duplicated(),该方法中两个主要的参数是 subset 和keep。


  • subset:要判断重复值的列,可以指定特定列或多个列。认使用全部列。
  • keep:当重复时不标记为True的规则,可设置为第1个(first)、最后一个(last)和全部标记为True(False)。认使用first,即第1个重复值不标记为True。


结果如下:


0    False
1    False
2     True
3    False
dtype: bool


4. 删除重复值


print(df.drop_duplicates())           # 删除数据记录中所有列值相同的记录
print(df.drop_duplicates(['col1']))       # 删除数据记录中col1值相同的记录
print(df.drop_duplicates(['col2']))       # 删除数据记录中col2值相同的记录
print(df.drop_duplicates(['col1', 'col2']))  # 删除数据记录中指定列(col1/col2)值相同的记录


该操作的核心方法是 df.drop_duplicates(),该方法的作用是基于指定的规则判断为重复值之后,删除重复值,其参数跟 df.duplicated() 完全相同。在该部分方法示例中,依次使用认规则(全部列相同的数据记录)、col1列相同、col2列相同以及指定col1和col2完全相同4种规则进行去重。返回结果如下。


删除数据记录中所有列值相同的记录,index为2的记录行被删除


  col1  col2
0    a     3
1    b     2
3    c     2


删除数据记录中col1值相同的记录,index为2的记录行被删除


  col1  col2
0    a     3
1    b     2
3    c     2


删除数据记录中col2值相同的记录,index为2和3的记录行被删除


  col1  col2
0    a     3
1    b     2


删除数据记录中指定列(col1和col2)值相同的记录,index为2的记录行被删除


  col1  col2
0    a     3
1    b     2
3    c     2


提示:由于数据是通过随机数产生,因此读者操作的结果可能与上述示例的数据结果不同。


除了可以使用Pandas来做重复值判断和处理外,也可以使用Numpy中的unique() 方法,该方法返回其参数数组中所有不同的值,并且按照从小到大的顺序排列。Python自带的内置函数 set 方法也能返回唯一元素的集合。


上述过程中,主要需要考虑的关键点是:如何对重复值进行处理。重复值的判断相对简单,而判断之后如何处理往往不是一个技术特征明显的工作,而是侧重于业务和建模需求的工作。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


我最近重新拾起了计算机视觉,借助Python的opencv还有face_recognition库写了个简单的图像识别demo,额外定制了一些内容,原本想打包成exe然后发给朋友,不过在这当中遇到了许多小问题,都解决了,记录一下踩过的坑。 1、Pyinstaller打包过程当中出现warning,跟d
说到Pooling,相信学习过CNN的朋友们都不会感到陌生。Pooling在中文当中的意思是“池化”,在神经网络当中非常常见,通常用的比较多的一种是Max Pooling,具体操作如下图: 结合图像理解,相信你也会大概明白其中的本意。不过Pooling并不是只可以选取2x2的窗口大小,即便是3x3,
记得大一学Python的时候,有一个题目是判断一个数是否是复数。当时觉得比较复杂不好写,就琢磨了一个偷懒的好办法,用异常处理的手段便可以大大程度帮助你简短代码(偷懒)。以下是判断整数和复数的两段小代码: 相信看到这里,你也有所顿悟,能拓展出更多有意思的方法~
文章目录 3 直方图Histogramplot1. 基本直方图的绘制 Basic histogram2. 数据分布与密度信息显示 Control rug and density on seaborn histogram3. 带箱形图的直方图 Histogram with a boxplot on t
文章目录 5 小提琴图Violinplot1. 基础小提琴图绘制 Basic violinplot2. 小提琴图样式自定义 Custom seaborn violinplot3. 小提琴图颜色自定义 Control color of seaborn violinplot4. 分组小提琴图 Group
文章目录 4 核密度图Densityplot1. 基础核密度图绘制 Basic density plot2. 核密度图的区间控制 Control bandwidth of density plot3. 多个变量的核密度图绘制 Density plot of several variables4. 边
首先 import tensorflow as tf tf.argmax(tenso,n)函数会返回tensor中参数指定的维度中的最大值的索引或者向量。当tensor为矩阵返回向量,tensor为向量返回索引号。其中n表示具体参数的维度。 以实际例子为说明: import tensorflow a
seaborn学习笔记章节 seaborn是一个基于matplotlib的Python数据可视化库。seaborn是matplotlib的高级封装,可以绘制有吸引力且信息丰富的统计图形。相对于matplotlib,seaborn语法更简洁,两者关系类似于numpy和pandas之间的关系,seabo
Python ConfigParser教程显示了如何使用ConfigParser在Python中使用配置文件。 文章目录 1 介绍1.1 Python ConfigParser读取文件1.2 Python ConfigParser中的节1.3 Python ConfigParser从字符串中读取数据
1. 处理Excel 电子表格笔记(第12章)(代码下载) 本文主要介绍openpyxl 的2.5.12版处理excel电子表格,原书是2.1.4 版,OpenPyXL 团队会经常发布新版本。不过不用担心,新版本应该在相当长的时间内向后兼容。如果你有新版本,想看看它提供了什么新功能,可以查看Open
1. 发送电子邮件和短信笔记(第16章)(代码下载) 1.1 发送电子邮件 简单邮件传输协议(SMTP)是用于发送电子邮件的协议。SMTP 规定电子邮件应该如何格式化、加密、在邮件服务器之间传递,以及在你点击发送后,计算机要处理的所有其他细节。。但是,你并不需要知道这些技术细节,因为Python 的
文章目录 12 绘图实例(4) Drawing example(4)1. Scatterplot with varying point sizes and hues(relplot)2. Scatterplot with categorical variables(swarmplot)3. Scat
文章目录 10 绘图实例(2) Drawing example(2)1. Grouped violinplots with split violins(violinplot)2. Annotated heatmaps(heatmap)3. Hexbin plot with marginal dist
文章目录 9 绘图实例(1) Drawing example(1)1. Anscombe’s quartet(lmplot)2. Color palette choices(barplot)3. Different cubehelix palettes(kdeplot)4. Distribution
Python装饰器教程展示了如何在Python中使用装饰器基本功能。 文章目录 1 使用教程1.1 Python装饰器简单示例1.2 带@符号的Python装饰器1.3 用参数修饰函数1.4 Python装饰器修改数据1.5 Python多层装饰器1.6 Python装饰器计时示例 2 参考 1 使
1. 用GUI 自动化控制键盘和鼠标第18章 (代码下载) pyautogui模块可以向Windows、OS X 和Linux 发送虚拟按键和鼠标点击。根据使用的操作系统,在安装pyautogui之前,可能需要安装一些其他模块。 Windows: 不需要安装其他模块。OS X: sudo pip3
文章目录 生成文件目录结构多图合并找出文件夹中相似图像 生成文件目录结构 生成文件夹或文件的目录结构,并保存结果。可选是否滤除目录,特定文件以及可以设定最大查找文件结构深度。效果如下: root:[z:/] |--a.py |--image | |--cat1.jpg | |--cat2.jpg |
文章目录 VENN DIAGRAM(维恩图)1. 具有2个分组的基本的维恩图 Venn diagram with 2 groups2. 具有3个组的基本维恩图 Venn diagram with 3 groups3. 自定义维恩图 Custom Venn diagram4. 精致的维恩图 Elabo
mxnet60分钟入门Gluon教程代码下载,适合做过深度学习的人使用。入门教程地址: https://beta.mxnet.io/guide/getting-started/crash-course/index.html mxnet安装方法:pip install mxnet 1 在mxnet中使
文章目录 1 安装2 快速入门2.1 基本用法2.2 输出图像格式2.3 图像style设置2.4 属性2.5 子图和聚类 3 实例4 如何进一步使用python graphviz Graphviz是一款能够自动排版的流程图绘图软件。python graphviz则是graphviz的python实