NumPy 中文教程

第一部分:基础认知与环境准备
第 1 章 全面认识 NumPy
第 2 章 开发环境搭建与验证
第二部分:核心对象 ——ndarray 数组
第 3 章 ndarray 数组基础
第 4 章 数组的形状与维度操作
第四部分:高级应用与数据处理
第 8 章 数组的排序、查找与去重
第 9 章 缺失值与异常值处理
第 10 章 随机数生成与抽样
第 11 章 文件读写与数据交互
第五部分:实战场景与落地应用
第 12 章 数值计算实战
第 13 章 数据分析实战
第六部分:优化进阶与问题解决
第 14 章 NumPy 性能优化
第 15 章 NumPy 进阶扩展
第 16 章 常见问题与解决方案

9.1 缺失值(NaN/Inf)处理

NumPy缺失值处理教程:检测、填充与删除NaN/Inf详解

NumPy 中文教程

本教程详细讲解NumPy中缺失值(NaN/Inf)的处理方法,包括生成与检测、多种填充策略(如均值、中位数、固定值)、删除技术(按行或按列)以及传播规则。适合初学者和高级用户学习,提升数据预处理能力。

推荐工具
PyCharm专业版开发必备

功能强大的Python IDE,提供智能代码补全、代码分析、调试和测试工具,提高Python开发效率。特别适合处理列表等数据结构的开发工作。

了解更多

NumPy缺失值处理全面指南

在数据科学和机器学习中,缺失值是常见的问题。NumPy作为Python中强大的数值计算库,提供了多种工具来处理缺失值,特别是NaN(Not a Number)和Inf(Infinity)。本教程将详细介绍如何生成、检测、填充、删除缺失值,并解释其传播规则,帮助新人轻松上手。

1. 缺失值的生成

1.1 NaN的生成

NaN表示无效或未定义的数字,通常在运算中意外产生或人为设置。在NumPy中,生成NaN的方法包括:

  • 使用np.nan常量直接创建,例如:arr = np.array([1, 2, np.nan, 4])
  • 通过某些数学运算,如除以零(在浮点数中会产生NaN),例如:result = 0.0 / 0.0 会得到NaN。
  • 使用函数如np.sqrt(-1)在实数域中产生NaN。

示例代码:

import numpy as np

# 生成包含NaN的数组
nan_arr = np.array([1.0, np.nan, 3.0, 4.0])
print("NaN数组:", nan_arr)

# 通过运算生成NaN
temp = np.array([1.0, 0.0])
print("除以零结果:", temp[1] / 0.0)  # 输出inf,但0/0会生成NaN

1.2 Inf的生成

Inf表示无穷大,通常由除以零或溢出运算产生。例如:

  • arr = np.array([1.0, 0.0]),然后arr[1] / 0.0会得到inf(正无穷)或-inf(负无穷)。
  • 使用np.inf常量,例如:inf_arr = np.array([1, np.inf, 3])

示例:

# 生成包含Inf的数组
inf_arr = np.array([1.0, np.inf, -np.inf, 4.0])
print("Inf数组:", inf_arr)

2. 缺失值的检测

NumPy提供了专门函数来检测NaN和Inf值,这对于数据清洗至关重要。

2.1 np.isnan()函数

检测数组中的NaN值,返回一个布尔数组,其中True表示对应位置是NaN。

arr = np.array([1.0, np.nan, 3.0, np.inf])
print("检测NaN:", np.isnan(arr))  # 输出:[False, True, False, False]

2.2 np.isinf()函数

检测数组中的Inf值(包括正无穷和负无穷)。

print("检测Inf:", np.isinf(arr))  # 输出:[False, False, False, True]

2.3 np.isfinite()函数

检测数组中的有限值(即非NaN和非Inf),返回布尔数组。

print("检测有限值:", np.isfinite(arr))  # 输出:[True, False, True, False]

这些函数支持数组操作,可以高效处理大规模数据。

3. 缺失值填充

处理缺失值时,填充是常见策略,NumPy提供了多种方法,但需注意使用忽略NaN的统计函数。

3.1 均值填充

使用np.nanmean()计算忽略NaN的均值,然后用该值填充NaN。np.nanmean()会自动跳过NaN进行计算。

arr = np.array([1.0, np.nan, 3.0, 4.0, np.nan])
mean_val = np.nanmean(arr)  # 计算均值,忽略NaN
print("忽略NaN的均值:", mean_val)
# 使用np.where填充
filled_arr = np.where(np.isnan(arr), mean_val, arr)
print("均值填充后数组:", filled_arr)

3.2 中位数填充

类似地,使用np.nanmedian()计算中位数并填充。

median_val = np.nanmedian(arr)
print("忽略NaN的中位数:", median_val)
filled_arr_median = np.where(np.isnan(arr), median_val, arr)
print("中位数填充后数组:", filled_arr_median)

3.3 固定值填充

用特定值(如0、-1或自定义值)替换所有NaN。这种方法简单直接,但可能引入偏差。

arr[np.isnan(arr)] = 0  # 将NaN替换为0
print("固定值填充后数组:", arr)

3.4 插值填充

对于序列数据,可以使用插值方法,如线性插值。NumPy没有内置的NaN插值函数,但可以结合其他库或手动实现。以下是一个简单示例,使用前后值的平均值填充NaN(假设数据有序)。

arr = np.array([1.0, np.nan, 3.0, np.nan, 5.0])
# 手动插值:用前一个非NaN值填充(简单方法)
for i in range(len(arr)):
    if np.isnan(arr[i]):
        # 查找前一个和后一个非NaN值,这里简化处理
        prev_val = arr[i-1] if i>0 and not np.isnan(arr[i-1]) else None
        next_val = arr[i+1] if i<len(arr)-1 and not np.isnan(arr[i+1]) else None
        if prev_val is not None and next_val is not None:
            arr[i] = (prev_val + next_val) / 2  # 线性插值
        elif prev_val is not None:
            arr[i] = prev_val  # 用前值填充
        elif next_val is not None:
            arr[i] = next_val  # 用后值填充
print("插值填充后数组:", arr)

在实际应用中,建议使用pandas库的fillna()方法进行更复杂的插值。

4. 缺失值删除

如果缺失值比例较高或影响分析,删除可能是更好的选择。NumPy允许按行或按列删除包含NaN的数据。

4.1 按行删除

删除任何包含NaN的行。使用np.any()结合np.isnan()和轴参数实现。

arr = np.array([[1.0, 2.0, np.nan],
                [4.0, 5.0, 6.0],
                [np.nan, 8.0, 9.0]])
# 检测每行是否有NaN
rows_with_nan = np.any(np.isnan(arr), axis=1)
print("行包含NaN:", rows_with_nan)  # 输出:[True, False, True]
# 删除包含NaN的行
cleaned_rows = arr[~rows_with_nan]
print("按行删除后数组:", cleaned_rows)

4.2 按列删除

删除任何包含NaN的列。类似地,使用轴参数调整。

cols_with_nan = np.any(np.isnan(arr), axis=0)
print("列包含NaN:", cols_with_nan)  # 输出:[True, False, True]
cleaned_cols = arr[:, ~cols_with_nan]
print("按列删除后数组:", cleaned_cols)

删除操作会减少数据量,需谨慎使用,避免丢失重要信息。

5. 缺失值传播规则

在NumPy运算中,NaN和Inf有特定的传播行为,了解这些规则有助于避免意外错误。

5.1 NaN传播规则

  • 算术运算:任何涉及NaN的运算结果通常为NaN。例如:np.nan + 1 返回NaN,np.nan * 2 返回NaN。
  • 比较运算:NaN不等于任何值,包括它自己。因此,np.nan == np.nan 返回False,np.nan != np.nan 返回True。使用np.isnan()进行检测。
  • 统计函数:标准统计函数如np.sum()np.mean()在遇到NaN时会返回NaN或错误。因此,应使用nan版本,如np.nansum()np.nanmean(),这些函数忽略NaN进行计算。

示例:

a = np.array([1.0, np.nan, 3.0])
print("总和(忽略NaN):", np.nansum(a))  # 输出4.0
print("总和(包含NaN):", np.sum(a))     # 输出nan

5.2 Inf传播规则

  • Inf在运算中通常按数学规则传播,例如np.inf + 1 返回inf,1 / np.inf 返回0。
  • 与NaN类似,Inf在某些统计函数中可能被忽略或导致错误,需注意处理。

示例:

b = np.array([np.inf, 2.0, 3.0])
print("Inf数组总和:", np.sum(b))  # 输出inf

总结

NumPy提供了强大的工具来处理缺失值(NaN/Inf),从生成和检测到填充、删除和传播规则。关键点包括:

  • 使用np.nannp.inf生成缺失值,通过运算如除以零引入。
  • 检测函数:np.isnan()np.isinf()np.isfinite()高效识别缺失值。
  • 填充策略:均值、中位数、固定值或插值填充,使用nan版本统计函数避免错误。
  • 删除方法:按行或按列删除包含NaN的数据,使用布尔索引。
  • 传播规则:NaN在运算中传播为NaN,Inf按数学规则传播,理解这些有助于数据清洗。

对于更复杂的缺失值处理,可以考虑结合pandas、scikit-learn等库。本教程旨在帮助新人快速掌握NumPy缺失值处理基础,提升数据预处理技能。实践时,多尝试代码示例,加深理解。

开发工具推荐
Python开发者工具包

包含虚拟环境管理、代码格式化、依赖管理、测试框架等Python开发全流程工具,提高开发效率。特别适合处理复杂数据结构和算法。

获取工具包