Python EXCEL 理论探究:格式转换时处理缺失值方法

发布于:2025-09-09 ⋅ 阅读:(21) ⋅ 点赞:(0)

使用 Python(特别是 pandas 的 read_excel() 函数)读取 Excel 文件时,处理各种错误值和空缺值是数据清洗的关键第一步。

1. Excel 中的错误类型和空缺类型

类型 Excel 中的表现 示例/原因
空单元格 完全没有任何内容 未输入数据
公式错误值 #DIV/0!, #N/A, #NAME?, #NULL!, #NUM!, #REF!, #VALUE! 公式计算错误、引用失效等
表示为空字符串 一个单引号 ' 或公式 ="" 用户手动输入或公式返回以表示“无”
表示为文本的“空” 字符串如 "null", "NULL", "NA", "N/A", "缺失" 用户习惯性输入
数字格式的“空” 数字如 -999, 0 有时被用作占位符或缺失值代码

2. pandas 默认读取行为

当使用 pd.read_excel(‘file.xlsx’) 时,pandas 会按照一套默认规则来处理上述情况:

  1. 真正的空单元格

    • 默认转换为 NaN(Not a Number),这是 pandas 中标记缺失值的标准标量值。在 DataFrame 中显示为 NaN
  2. Excel 公式错误值(如 #DIV/0!, #N/A

    • 行为因 pandas 和引擎版本而异,但通常也会被转换为 NaN
      • 现代版本的 openpyxlxlrd 引擎通常能很好地处理,将这些错误直接解析为 NaN,这是最理想的情况。
      • 在某些旧版本或特定环境下,这些错误值可能导致读取过程抛出异常,而不是安静地转换为 NaN。最佳实践是预先处理或之后检查。
  3. 空字符串 ""

    • 默认被保留为 Python 的空字符串对象 ""不会被转换为 NaN
    • 这意味着 DataFrame 可能会混合两种“空”:NaN(来自真正空单元格)和 ""(来自空字符串)。这在后续处理时需要特别注意,因为 df[‘col’].isna() 会过滤掉 NaN,但不会过滤掉 ""
  4. 文本字符串(如 “NULL“, “NA“, “N/A“)

    • 默认被保留为普通的字符串 "NULL", "NA", "N/A"。它们不会被自动识别为缺失值。

3. 主动控制和处理:read_excel() 的关键参数

na_values 参数

这是最重要的参数,用于指定哪些附加的字符串应被识别为 NaN/缺失值

  • 作用:提供一个列表,列表中的每个值在读取时都会被转换为 NaN
  • 示例
    import pandas as pd
    
        # 将常见的表示“空”的字符串和数字都识别为 NaN
    df = pd.read_excel(
        'data.xlsx',  # 文件名使用英文单引号
        na_values=['', '#N/A', '#N/A N/A', '#NA', '-1.#IND', '-1.#QNAN',
                   '-NaN', '-nan', '1.#IND', '1.#QNAN', '<NA>', 'N/A',
                   'NA', 'NULL', 'NaN', 'n/a', 'nan', 'null', '缺失', -999, 0] 
    )
    
    • 这样,Excel 中无论是真正的空单元格、还是用户输入的 “NA"“NULL”,甚至是占位数字 -9990,都会被统一转换为 pandas 的 NaN,极大简化后续处理。

keep_default_na 参数

这个参数与 na_values 配合使用,控制是否保留 pandas 默认的缺失值识别列表。

  • keep_default_na=True (默认值):

    • pandas 会使用其内置的长列表(包括空字符串 """#N/A""#N/A N/A""#NA""-1.#IND""-1.#QNAN""-NaN""-nan""1.#IND""1.#QNAN""<NA>""N/A""NA""NULL""NaN""n/a""nan""null")来识别缺失值。
    • 再加上 na_values 中指定的任何值。
  • keep_default_na=False:

    • 只有 na_values 参数中指定的值才会被识别为 NaN
    • False: 关闭pandas 所有的默认缺失值识别。
    • 真正的空单元格仍然会被转换为 NaN,不受此参数影响。
    • 使用场景:当用户想要完全自定义什么才算是缺失值时。例如,如果数据中合法地包含了 "NA" 这个字符串(如国家代码)。
    # 只将我自定义的值视为缺失值,忽略pandas的所有默认设置
    df = pd.read_excel(
        ‘data.xlsx‘,
        keep_default_na=False,
        na_values=[‘自定义空‘, ‘无效值‘, -1] # 只有这三个和真正空单元格会是NaN
    )
    

4. 读取后的检查和处理

  1. 检查缺失值

    # 显示每列的缺失值总数
    print(df.isna().sum())
    
    # 显示整个DataFrame的缺失值热力图(用于可视化)
    import seaborn as sns
    sns.heatmap(df.isna(), cbar=False)
    
  2. 处理混合的空字符串和 NaN
    如果读取时没有使用 na_values 处理空字符串 "",数据中就会混合了 NaN""

    # 方法一:将空字符串替换为 NaN(推荐,便于统一处理)
    df.replace(‘‘, pd.NA, inplace=True) # 对于字符串列,pd.NA 是新的缺失值标志
    # 或者更通用的写法
    df = df.replace(‘‘, np.nan) # 对于混合类型数据,np.nan 更通用
    
    # 方法二:统一过滤(查找所有“空”,包括NaN和空字符串)
    # isnan() 不认识字符串,所以需要组合条件
    empty_mask = df[‘column_name‘].isna() | (df[‘column_name‘] == ‘‘)
    
  3. 处理意外残留的错误值
    极少数情况下,可能有错误值没被正确转换,在 DataFrame 中显示为字符串,如 ‘#DIV/0!‘

    # 手动将它们替换为 NaN
    error_list = [#DIV/0!‘, ‘#NAME?‘, ‘#NUM!‘, ‘#VALUE!‘, ‘#REF!‘, ‘#NULL!‘]
    df = df.replace(error_list, np.nan)
    

最佳实践总结

  1. 显式优于隐式:不要依赖默认行为。在读取 Excel 时,始终使用 na_values 参数来明确指定哪些值应被视为缺失值。
  2. 理解 keep_default_na:判断是 扩充 默认列表(keep_default_na=True)还是 替换keep_default_na=False)。
  3. 读取后立即验证:使用 df.info()df.isna().sum() 快速检查数据类型和缺失值情况。
  4. 统一“空”的表示:确保 DataFrame 中只有一种表示缺失值的方式(通常是 NaN/pd.NA),而不是混合着 NaN""“NULL” 等。这为后续的填充、删除或计算操作扫清障碍。
  5. 注意数据类型:强制转换错误值或占位数字(如 -999)为 NaN 后,相关列的数据类型可能会发生变化(例如从 int64 变为 float64),这是正常现象,因为整数类型无法原生表示 NaN

网站公告

今日签到

点亮在社区的每一天
去签到