Python Pandas 的数据清理功能强大,常用于处理缺失值、重复数据、不规范格式和异常值等问题,常见操作包括使用 isnull() 检查缺失、dropna() 删除缺失行、fillna() 填充缺失值、drop_duplicates() 去重、字符串清洗、类型转换和异常值过滤,帮助提升数据质量,为后续分析和建模打下坚实基础,是数据分析和机器学习前不可或缺的重要步骤,本文主要介绍Python Pandas 数据清理。

1、数据清理(Data Cleaning)

数据清理(Data Cleaning) 是数据分析中最关键的步骤之一,它指的是识别并修复数据集中存在的“错误数据”或“不一致数据”,以提高数据质量,确保分析结果的准确性。

常见的数据错误类型,如下表,

    错误类型描述说明
    空单元格某些值缺失(NaN)
    数据格式错误如日期、数字、字符串类型不一致
    数据内容错误如性别列出现拼写错误(如 "Malee")
    重复数据多行数据完全重复,影响统计分析

    数据清理是指修复数据集中的错误信息,包括处理空单元格、格式错误、错误数据和重复项等问题。通过数据清理,可以提高数据的准确性和一致性,是数据分析和建模前的重要准备工作。

    2、示例数据集

    示例数据集:

          Duration          Date  Number  Count Calories
      0         60  '2020/12/01'    110       130     409.1
      1         60  '2020/12/02'    117       145     479.0
      2         60  '2020/12/03'    103       135     340.0
      3         45  '2020/12/04'    109       175     282.4
      4         45  '2020/12/05'    117       148     406.0
      5         60  '2020/12/06'    102       127     300.0
      6         60  '2020/12/07'    110       136     374.0
      7        450  '2020/12/08'    104       134     253.3
      8         30  '2020/12/09'    109       133     195.1
      9         60  '2020/12/10'     98       124     269.0
      10        60  '2020/12/11'    103       147     329.3
      11        60  '2020/12/12'    100       120     250.7
      12        60  '2020/12/12'    100       120     250.7
      13        60  '2020/12/13'    106       128     345.3
      14        60  '2020/12/14'    104       132     379.3
      15        60  '2020/12/15'     98       123     275.0
      16        60  '2020/12/16'     98       120     215.2
      17        60  '2020/12/17'    100       120     300.0
      18        45  '2020/12/18'     90       112       NaN
      19        60  '2020/12/19'    103       123     323.0
      20        45  '2020/12/20'     97       125     243.0
      21        60  '2020/12/21'    108       131     364.2
      22        45           NaN    100       119     282.0
      23        60  '2020/12/23'    130       101     300.0
      24        45  '2020/12/24'    105       132     246.0
      25        60  '2020/12/25'    102       126     334.5
      26        60  '2020/12/26'    100       120     250.0
      27        60  '2020/12/27'     92       118     241.0
      28        60  '2020/12/28'    103       132       NaN
      29        60  '2020/12/29'    100       132     280.0
      30        60  '2020/12/30'    102       129     380.3
      31        60  '2020/12/31'     92       115     243.0

    数据集包含一些空单元格 (22行中"Date"列, 及18和28行中"Calories"列)。
    数据集包含错误的格式 (26行中"Date"列)。
    数据集包含错误的数据 (7行中"Duration"列)。
    数据集包含重复数据 ( 11和12行)。

    3、Pandas 清洗空值

    如要删除包含空字段的行,可以使用 dropna() 。还可以使用 fillna() 方法来替换一些空字段

    import pandas as pd
    import numpy as np
    
    data = {
        'Duration': [60, 60, 60, 45, 45, 60, 60, 450, 30,
        60],
        'Date': ['2020/12/01', '2020/12/02', '2020/12/03',
        '2020/12/04', '2020/12/05',
                 '2020/12/06', '2020/12/07', '2020/12/08',
                 '2020/12/09', np.nan],
        'Number': [110, 117, 103, 109, 117, 102, 110, 104,
        109, 130],
        'Count': [130, 145, 135, 175, 148, 127, 136, 134,
        133, 101],
        'Calories': [409.1, 479.0, 340.0, 282.4, 406.0, 
        300.0, 374.0, 253.3, 195.1, np.nan]
    }
    
    df = pd.DataFrame(data)
    # 检查缺失值,返回布尔型DataFrame
    print(df.isnull())      
    # 每列缺失值数量
    print(df.isnull().sum())
    # 删除含缺失值的行
    print(df.dropna()) 
    # 用 0 填充所有缺失值
    print(df.fillna(0))      
    # 用均值填充某列缺失值
    print(df['Calories'].fillna(df['Calories'].mean())) 

    参考文档:

    Python pandas.DataFrame.dropna函数方法的使用

    Python pandas.DataFrame.fillna函数方法的使用

    1)删除包含空数据的行

    import pandas as pd
    
    df = pd.read_csv('data.csv')
    # 默认情况下,dropna() 方法返回一个新的 DataFrame,不会修改源数据。
    # 如需要修改源数据,则需要使用df.dropna(inplace = True)
    new_df = df.dropna()
    
    print(new_df.to_string())

    输出结果:

          Duration          Date  Number  Count Calories
      0         60  '2020/12/01'    110       130     409.1
      1         60  '2020/12/02'    117       145     479.0
      2         60  '2020/12/03'    103       135     340.0
      3         45  '2020/12/04'    109       175     282.4
      4         45  '2020/12/05'    117       148     406.0
      5         60  '2020/12/06'    102       127     300.0
      6         60  '2020/12/07'    110       136     374.0
      7        450  '2020/12/08'    104       134     253.3
      8         30  '2020/12/09'    109       133     195.1
      9         60  '2020/12/10'     98       124     269.0
      10        60  '2020/12/11'    103       147     329.3
      11        60  '2020/12/12'    100       120     250.7
      12        60  '2020/12/12'    100       120     250.7
      13        60  '2020/12/13'    106       128     345.3
      14        60  '2020/12/14'    104       132     379.3
      15        60  '2020/12/15'     98       123     275.0
      16        60  '2020/12/16'     98       120     215.2
      17        60  '2020/12/17'    100       120     300.0
      18        60  '2020/12/19'    103       123     323.0
      19        45  '2020/12/20'     97       125     243.0
      20        60  '2020/12/21'    108       131     364.2
      21        60  '2020/12/23'    130       101     300.0
      22        45  '2020/12/24'    105       132     246.0
      23        60  '2020/12/25'    102       126     334.5
      24        60  '2020/12/26'    100       120     250.0
      25        60  '2020/12/27'     92       118     241.0
      26        60  '2020/12/29'    100       132     280.0
      27        60  '2020/12/30'    102       129     380.3
      28        60  '2020/12/31'     92       115     243.0    

    2)移除指定列有空值的行

    import pandas as pd
    
    df = pd.read_csv('data.csv')
    
    df.dropna(subset=['Calories'], inplace = True)
    
    print(df.to_string())

    输出结果:

          Duration          Date  Number  Count Calories
      0         60  '2020/12/01'    110       130     409.1
      1         60  '2020/12/02'    117       145     479.0
      2         60  '2020/12/03'    103       135     340.0
      3         45  '2020/12/04'    109       175     282.4
      4         45  '2020/12/05'    117       148     406.0
      5         60  '2020/12/06'    102       127     300.0
      6         60  '2020/12/07'    110       136     374.0
      7        450  '2020/12/08'    104       134     253.3
      8         30  '2020/12/09'    109       133     195.1
      9         60  '2020/12/10'     98       124     269.0
      10        60  '2020/12/11'    103       147     329.3
      11        60  '2020/12/12'    100       120     250.7
      12        60  '2020/12/12'    100       120     250.7
      13        60  '2020/12/13'    106       128     345.3
      14        60  '2020/12/14'    104       132     379.3
      15        60  '2020/12/15'     98       123     275.0
      16        60  '2020/12/16'     98       120     215.2
      17        60  '2020/12/17'    100       120     300.0
      18        60  '2020/12/19'    103       123     323.0
      19        45  '2020/12/20'     97       125     243.0
      20        60  '2020/12/21'    108       131     364.2
      21        45           NaN    100       119     282.0
      22        60  '2020/12/23'    130       101     300.0
      23        45  '2020/12/24'    105       132     246.0
      24        60  '2020/12/25'    102       126     334.5
      25        60  '2020/12/26'    100       120     250.0
      26        60  '2020/12/27'     92       118     241.0
      27        60  '2020/12/29'    100       132     280.0
      28        60  '2020/12/30'    102       129     380.3
      29        60  '2020/12/31'     92       115     243.0    

     3)使用 0 替换空字段

    import pandas as pd
    
    df = pd.read_csv('property-data.csv')
    # 默认情况下,fillna() 方法返回一个新的 DataFrame,不会修改源数据。
    # 如需要修改源数据,则需要使用inplace = True
    df.fillna(0, inplace = True)
    
    print(df.to_string())

    输出结果:

          Duration          Date  Number  Count Calories
      0         60  '2020/12/01'    110       130     409.1
      1         60  '2020/12/02'    117       145     479.0
      2         60  '2020/12/03'    103       135     340.0
      3         45  '2020/12/04'    109       175     282.4
      4         45  '2020/12/05'    117       148     406.0
      5         60  '2020/12/06'    102       127     300.0
      6         60  '2020/12/07'    110       136     374.0
      7        450  '2020/12/08'    104       134     253.3
      8         30  '2020/12/09'    109       133     195.1
      9         60  '2020/12/10'     98       124     269.0
      10        60  '2020/12/11'    103       147     329.3
      11        60  '2020/12/12'    100       120     250.7
      12        60  '2020/12/12'    100       120     250.7
      13        60  '2020/12/13'    106       128     345.3
      14        60  '2020/12/14'    104       132     379.3
      15        60  '2020/12/15'     98       123     275.0
      16        60  '2020/12/16'     98       120     215.2
      17        60  '2020/12/17'    100       120     300.0
      18        45  '2020/12/18'     90       112       0
      19        60  '2020/12/19'    103       123     323.0
      20        45  '2020/12/20'     97       125     243.0
      21        60  '2020/12/21'    108       131     364.2
      22        45           0    100       119     282.0
      23        60  '2020/12/23'    130       101     300.0
      24        45  '2020/12/24'    105       132     246.0
      25        60  '2020/12/25'    102       126     334.5
      26        60   ‘2020/12/26’    100       120     250.0
      27        60  '2020/12/27'     92       118     241.0
      28        60  '2020/12/28'    103       132       0
      29        60  '2020/12/29'    100       132     280.0
      30        60  '2020/12/30'    102       129     380.3
      31        60  '2020/12/31'     92       115     243.0    

    4、Pandas 清洗格式错误数据

    有数据格式错误的单元格,可以通过将空单元格的行,或者将列中的所有单元格转换为相同格式的数据。

    import pandas as pd
    
    # 第三个日期格式错误
    data = {
      "Date": ['2022/11/01', '2022/11/02' , '20221126'],
      "Count": [50, 40, 45]
    }
    
    df = pd.DataFrame(data, index = ["day1", "day2", "day3"])
    
    df['Date'] = pd.to_datetime(df['Date'])
    
    print(df.to_string())

    5、Pandas 清洗错误数据

    对于错误数据的清洗,可以尝试对错误的数据进行替换或删除。

    import pandas as pd
    
    data = {
      "name": ['Python', 'Java' , 'C'],
      "count": [1, 2, -1]    # -1的数据是有问题
    }
    
    df = pd.DataFrame(data)
    
    for x in df.index:
      if df.loc[x, "count"] < 0:
        df.drop(x, inplace = True)
    
    print(df.to_string())

    6、Pandas 清洗重复数据

    对重复数据的清洗,可以使用duplicated()drop_duplicates()

    相关文档:

    Python pandas.DataFrame.duplicated函数方法的使用

    Python pandas.DataFrame.drop_duplicates函数方法的使用

    import pandas as pd
    
    data = {
      "name": ['Levi', 'Levi', 'Lynn', 'John'],
      "age": [30, 30, 20, 23]  
    }
    df = pd.DataFrame(data)
    
    print(df.duplicated())
    
    df.drop_duplicates(inplace = True)
    print(df)

    7、重命名列名和替换值

    重命名列名可以使用 rename(columns={...}) 方法,将原始列名修改为更清晰或规范的名称;而通过 replace({...}) 方法可对列中的特定值进行替换,这两种操作常用于数据清洗和格式标准化,提升数据的可读性与一致性。

    import pandas as pd
    
    # 构造示例 DataFrame
    data = {
        'Name': ['张三', '李四', '王五', '孙六'],
        'gender': ['F', 'M', 'M', 'F'],
        'score': [85, 90, 78, 92]
    }
    
    df = pd.DataFrame(data)
    print("原始数据:")
    print(df)
    
    # 重命名列
    df.rename(columns={'Name': 'NewName'}, inplace=True)
    print(df)
    # 替换值
    df['gender'].replace({'M': 'Male', 
    'F': 'Female'},inplace=True)
    print(df)
    

    推荐文档