数据清洗必看:NumPy 中 nan 的常见误区与替代方案

2025-12-04

咱们先来看看一些常见的问题、为什么会发生,以及如何优雅地处理它们。

这是初学者最容易犯的错误!在数学上,缺失值不能和任何东西相等,包括它自己。

问题描述 你想找出数组中所有的 nan 值,然后尝试用 arr == np.nan。

结果 得到的布尔数组中,所有元素都是 False。

原因 np.nan 自身比较永远返回 False (即 np.nan == np.nan 是 False)。

错误示例

import numpy as np

arr = np.array([1.0, 2.0, np.nan, 4.0])

print("arr == np.nan 的结果:", arr == np.nan)

# 输出: [False False False False]

解决方案使用 np.isnan()

要检查一个值是不是 nan,必须使用 np.isnan() 函数。

import numpy as np

arr = np.array([1.0, 2.0, np.nan, 4.0])

# 使用 np.isnan() 进行判断

is_nan = np.isnan(arr)

print("使用 np.isnan() 的结果:", is_nan)

# 输出: [False False True False]

# 配合布尔索引来选择或操作 nan 值

nan_values = arr[is_nan]

print("数组中的 nan 值:", nan_values)

# 输出: [nan]

当你对包含 nan 的数组进行求和、求平均值等操作时,结果可能不是你想要的。

问题描述 使用 np.sum(), np.mean(), np.std() 等标准函数计算包含 nan 值的数组。

结果 整个结果可能直接变成 nan (取决于具体操作和 NumPy 版本,但常见情况是 nan)。

原因 任何涉及到 nan 的算术运算,其结果通常也是 nan。

错误示例

import numpy as np

arr_with_nan = np.array([1.0, 2.0, np.nan, 4.0])

# 错误地计算平均值 (结果为 nan)

mean_val = np.mean(arr_with_nan)

print("错误计算的平均值:", mean_val)

# 输出: nan

解决方案使用 nan 安全的统计函数

NumPy 提供了一套特殊的函数,它们会自动忽略 nan 值进行计算。这些函数通常以 nan 开头

np.nansum()

np.nanmean()

np.nanmedian()

np.nanstd()

import numpy as np

arr_with_nan = np.array([1.0, 2.0, np.nan, 4.0])

# 正确计算平均值 (忽略 nan)

mean_val_safe = np.nanmean(arr_with_nan)

print("正确计算的平均值 (nanmean):", mean_val_safe)

# 输出: 2.3333333333333335 (即 (1+2+4)/3)

处理 nan 主要是两个方向删除 或 填充/替换。

如果你确定 nan 所在的数据记录没有价值,可以直接删除它们。

原理 使用 np.isnan() 配合布尔索引,只保留那些不是 nan 的元素。

示例代码删除 nan 元素

import numpy as np

data = np.array([10, 20, np.nan, 40, np.nan, 60])

# 1. 找出不是 nan 的元素 (使用逻辑非 ~)

not_nan = ~np.isnan(data)

# 2. 筛选出这些非 nan 元素

clean_data = data[not_nan]

print("原始数据:", data)

print("清除 nan 后的数据:", clean_data)

# 输出: [10. 20. 40. 60.]

在很多情况下,数据不能轻易删除,我们需要用一个估计值来替代 nan,比如 0、平均值、中位数等。

原理 结合 np.isnan() 和布尔索引,直接赋值。

示例代码用 0 替换 nan

import numpy as np

arr = np.array([1.0, 2.0, np.nan, 4.0, np.nan, 6.0])

# 找出所有 nan 的位置

nan_mask = np.isnan(arr)

# 将这些位置的值设置为 0

arr[nan_mask] = 0

print("用 0 替换 nan 后的数组:", arr)

# 输出: [1. 2. 0. 4. 0. 6.]

原理 先计算非 nan 值的平均值 (np.nanmean()),然后用这个平均值去替换所有的 nan。

示例代码用平均值替换 nan

import numpy as np

arr = np.array([1.0, 2.0, np.nan, 4.0, np.nan, 6.0])

# 1. 计算非 nan 数据的平均值

mean_val = np.nanmean(arr)

print(f"非 nan 数据的平均值: {mean_val:.2f}")

# 2. 找出 nan 的位置

nan_mask = np.isnan(arr)

# 3. 用平均值替换 nan

arr[nan_mask] = mean_val

print("用平均值替换 nan 后的数组:", arr)

# 输出: [1. 2. 3.2 4. 3.2 6. ] (3.2 是 (1+2+4+6)/4 的结果)

希望这份整理对你有所帮助!处理缺失值是数据分析的第一步,熟练掌握这些方法能让你事半功倍!