0

0

利用NumPy处理3D数组中包含NaN值的列均值计算与填充

碧海醫心

碧海醫心

发布时间:2025-10-06 11:53:11

|

999人浏览过

|

来源于php中文网

原创

利用NumPy处理3D数组中包含NaN值的列均值计算与填充

本教程旨在解决如何在3D NumPy数组中,为每个2D子数组计算其列的均值(忽略NaN值),并使用这些计算出的均值来填充原始数组中的NaN值。文章将详细介绍如何利用np.nanmean函数进行NaN-aware的均值计算,并通过np.newaxis进行数组维度扩展以实现正确的广播操作,最终完成数据的清洗和填充。

问题场景描述

在数据处理中,我们经常会遇到多维数组中包含缺失值(nan)的情况。例如,一个3d numpy数组可能代表了多组(第一维度)2d数据,每组2d数据又包含行和列。我们的目标是针对每一组2d数据,计算其所有列的均值,同时忽略计算中的nan值,然后用这些计算出的列均值来填充原始数组中对应列的nan值。

考虑以下一个形状为(2, 3, 3)的3D NumPy数组作为示例:

import numpy as np

a = np.array([[[1, 2, 3], [4, np.nan, 6], [7, 8, 9]],
             [[11, 12, 13], [14, np.nan, 16], [17, 18, 19]]])

print("原始数组形状:", a.shape)
print("原始数组:\n", a)

输出:

原始数组形状: (2, 3, 3)
原始数组:
 [[[ 1.  2.  3.]
  [ 4. nan  6.]
  [ 7.  8.  9.]]

 [[11. 12. 13.]
  [14. nan 16.]
  [17. 18. 19.]]]

在这个数组中,a[0]和a[1]分别代表了两组2D数据。我们希望对a[0]的第二列(索引为1)计算均值,即(2 + 8) / 2 = 5,然后用5填充a[0, 1, 1]处的NaN。同样,对于a[1]的第二列,计算均值(12 + 18) / 2 = 15,并用15填充a[1, 1, 1]处的NaN。

期望的结果数组如下:

[[[ 1.,  2.,  3.],
  [ 4.,  5.,  6.],
  [ 7.,  8.,  9.]],

 [[11., 12., 13.],
  [14., 15., 16.],
  [17., 18., 19.]]]

解决方案:使用 np.nanmean 和广播机制

NumPy提供了一个专门用于处理包含NaN值的均值计算函数 np.nanmean()。结合NumPy强大的广播(broadcasting)机制,我们可以高效地实现上述目标。

1. 计算列均值(忽略NaN)

首先,我们需要计算每个2D子数组的列均值。对于一个形状为(dim0, dim1, dim2)的3D数组,如果我们想计算每个dim0切片(即每个2D子数组)的列均值,我们需要指定axis=1。这是因为axis=0代表第一个维度(2D子数组的索引),axis=1代表第二个维度(2D子数组的行索引),axis=2代表第三个维度(2D子数组的列索引)。当我们对axis=1求均值时,它会沿着行方向进行聚合,从而得到每列的均值。

# 计算每个2D子数组的列均值,忽略NaN值
# axis=1 表示在第二个维度上进行求均值操作,即对每个2D切片的列求均值
means = np.nanmean(a, axis=1)
print("\n计算出的列均值 (shape: {}):\n{}".format(means.shape, means))

输出:

计算出的列均值 (shape: (2, 3)):
[[ 4.  5.  6.]
 [14. 15. 16.]]

这里,means数组的形状是(2, 3)。means[0]对应原始数组a[0]的列均值 [4., 5., 6.],其中5.是(2+8)/2的结果。means[1]对应a[1]的列均值 [14., 15., 16.],其中15.是(12+18)/2的结果。

Thiings
Thiings

免费的拟物化图标库

下载

2. 调整均值数组的形状以进行广播

现在我们有了每个2D子数组的列均值,但means的形状是(2, 3),而原始数组a的形状是(2, 3, 3)。为了使用np.where函数将这些均值正确地广播到原始数组的相应NaN位置,我们需要将means的形状调整为(2, 1, 3)。通过在第二个维度上添加一个新轴(np.newaxis),可以实现这一点。

# 调整均值数组的形状,使其能够正确广播
# means[:, np.newaxis, :] 将形状从 (2, 3) 变为 (2, 1, 3)
means_reshaped = means[:, np.newaxis, :]
print("\n重塑后的列均值 (shape: {}):\n{}".format(means_reshaped.shape, means_reshaped))

输出:

重塑后的列均值 (shape: (2, 1, 3)):
[[[ 4.  5.  6.]]

 [[14. 15. 16.]]]

现在,means_reshaped的形状是(2, 1, 3)。当它与形状为(2, 3, 3)的原始数组a进行广播操作时:

  • 第一个维度:2 与 2 匹配。
  • 第二个维度:1 与 3 匹配(1会被扩展到3)。
  • 第三个维度:3 与 3 匹配。 这样,每个2D子数组的列均值就能正确地应用到其所有行。

3. 填充NaN值

最后一步是使用np.where()函数来条件性地替换NaN值。np.where(condition, x, y)的含义是:如果condition为真,则取x中的值;否则,取y中的值。

# 使用np.where函数填充NaN值
# 如果a中的元素是NaN,则用重塑后的列均值填充;否则保留a中的原始值
a_filled = np.where(np.isnan(a), means_reshaped, a)
print("\n填充NaN后的数组:\n", a_filled)

输出:

填充NaN后的数组:
 [[[ 1.  2.  3.]
  [ 4.  5.  6.]
  [ 7.  8.  9.]]

 [[11. 12. 13.]
  [14. 15. 16.]
  [17. 18. 19.]]]

可以看到,原始数组中的NaN值已经被正确地替换为对应列的均值。

完整代码示例

import numpy as np

# 原始3D数组,包含NaN值
a = np.array([[[1, 2, 3], [4, np.nan, 6], [7, 8, 9]],
             [[11, 12, 13], [14, np.nan, 16], [17, 18, 19]]])

print("原始数组:\n", a)
print("原始数组形状:", a.shape)

# 1. 计算每个2D子数组的列均值,忽略NaN
# axis=1 表示在第二个维度上进行求均值,即对每个2D切片的列求均值
means = np.nanmean(a, axis=1)
print("\n计算出的列均值 (shape: {}):\n{}".format(means.shape, means))

# 2. 调整均值数组的形状以进行广播
# np.newaxis 在指定位置插入一个新维度,将 (2, 3) 变为 (2, 1, 3)
means_reshaped = means[:, np.newaxis, :]
print("\n重塑后的列均值 (shape: {}):\n{}".format(means_reshaped.shape, means_reshaped))

# 3. 使用np.where填充NaN值
# 如果a中的元素是NaN,则用重塑后的列均值填充;否则保留a中的原始值
a_filled = np.where(np.isnan(a), means_reshaped, a)
print("\n填充NaN后的数组:\n", a_filled)

注意事项与总结

  • np.nanmean() 的重要性: 当数据中存在NaN值时,使用标准的np.mean()会导致结果为NaN。np.nanmean()则会自动忽略NaN值进行计算,这在数据清洗中非常有用。
  • 轴(axis)的理解: 在多维数组操作中,正确理解axis参数至关重要。axis=1在3D数组(dim0, dim1, dim2)中意味着沿着dim1方向(即行方向)进行操作,从而聚合得到每列的结果。
  • 广播(Broadcasting)机制: NumPy的广播机制允许不同形状的数组进行算术运算,但前提是它们的维度能够兼容。通过np.newaxis手动扩展维度是实现兼容性的一种常见且强大的方法。在本例中,将(2, 3)的均值数组重塑为(2, 1, 3)是实现正确广播的关键。
  • np.where() 的应用: np.where()是一个非常灵活的函数,可以根据条件进行元素级的选择和替换,是处理条件逻辑的强大工具

通过掌握np.nanmean()、np.newaxis和np.where()的组合使用,可以高效且优雅地处理NumPy多维数组中包含NaN值的复杂数据清洗和填充任务。

相关专题

更多
go语言 数组和切片
go语言 数组和切片

本专题整合了go语言数组和切片的区别与含义,阅读专题下面的文章了解更多详细内容。

46

2025.09.03

html编辑相关教程合集
html编辑相关教程合集

本专题整合了html编辑相关教程合集,阅读专题下面的文章了解更多详细内容。

16

2026.01.21

三角洲入口地址合集
三角洲入口地址合集

本专题整合了三角洲入口地址合集,阅读专题下面的文章了解更多详细内容。

17

2026.01.21

AO3中文版入口地址大全
AO3中文版入口地址大全

本专题整合了AO3中文版入口地址大全,阅读专题下面的的文章了解更多详细内容。

215

2026.01.21

妖精漫画入口地址合集
妖精漫画入口地址合集

本专题整合了妖精漫画入口地址合集,阅读专题下面的文章了解更多详细内容。

57

2026.01.21

java版本选择建议
java版本选择建议

本专题整合了java版本相关合集,阅读专题下面的文章了解更多详细内容。

3

2026.01.21

Java编译相关教程合集
Java编译相关教程合集

本专题整合了Java编译相关教程,阅读专题下面的文章了解更多详细内容。

14

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

6

2026.01.21

无人机驾驶证报考 uom民用无人机综合管理平台官网
无人机驾驶证报考 uom民用无人机综合管理平台官网

无人机驾驶证(CAAC执照)报考需年满16周岁,初中以上学历,身体健康(矫正视力1.0以上,无严重疾病),且无犯罪记录。个人需通过民航局授权的训练机构报名,经理论(法规、原理)、模拟飞行、实操(GPS/姿态模式)及地面站训练后考试合格,通常15-25天拿证。

22

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.9万人学习

Pandas 教程
Pandas 教程

共15课时 | 0.9万人学习

ASP 教程
ASP 教程

共34课时 | 3.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号