当前位置: 首页 > news >正文

python | numpy小记(八):理解 NumPy 中的 `np.meshgrid`

python | numpy小记(八):理解 NumPy 中的 `np.meshgrid`

      • 一、核心思想:从“轴”到“网”
      • 二、工作原理与详细示例
      • 三、为什么它如此有用?——矢量化计算
      • 四、进阶用法
        • 1. 绘制三维曲面和等高线图
        • 2. `indexing` 参数
      • 总结


一、核心思想:从“轴”到“网”

想象一下,你正在一张白纸上画一个坐标网格。

  1. 首先,你在 x 轴(横轴)上标记了几个点,比如 x = [1, 2, 3]
  2. 然后,你在 y 轴(纵轴)上标记了几个点,比如 y = [10, 20, 30, 40]

现在,这些标记的点定义了一个网格。这个网格上有很多交叉点,它们的坐标分别是:
(1, 10), (2, 10), (3, 10)
(1, 20), (2, 20), (3, 20)
(1, 30), (2, 30), (3, 30)
(1, 40), (2, 40), (3, 40)

现在问题来了:如果我想对每一个网格点进行计算(比如计算 z = f(x, y)),我需要一种方法来轻松地获取每个点的 xy 坐标。

numpy.meshgrid 的作用就是帮你解决这个问题。它接收代表坐标轴上点的一维向量(如上面的 xy),然后生成两个二维矩阵(我们通常称之为 XXYY)。这两个矩阵包含了网格上每个点的x坐标和y坐标。

  • XX 矩阵:存储了网格中每一个点x 坐标
  • YY 矩阵:存储了网格中每一个点y 坐标

二、工作原理与详细示例

让我们用上面那个简单的例子来看看 meshgrid 是如何工作的。

import numpy as np# 1. 定义x轴和y轴上的点
x = np.array([1, 2, 3])      # 长度为 3
y = np.array([10, 20, 30, 40]) # 长度为 4# 2. 使用 meshgrid 生成坐标矩阵
XX, YY = np.meshgrid(x, y)# 3. 打印输出,观察结果
print("原始 x 向量:\n", x)
print("原始 y 向量:\n", y)
print("-" * 20)
print("生成的 XX 矩阵 (x-coordinates):\n", XX)
print("XX 矩阵的形状:", XX.shape)
print("-" * 20)
print("生成的 YY 矩阵 (y-coordinates):\n", YY)
print("YY 矩阵的形状:", YY.shape)

输出结果:

原始 x 向量:[1 2 3]
原始 y 向量:[10 20 30 40]
--------------------
生成的 XX 矩阵 (x-coordinates):[[1 2 3][1 2 3][1 2 3][1 2 3]]
XX 矩阵的形状: (4, 3)
--------------------
生成的 YY 矩阵 (y-coordinates):[[10 10 10][20 20 20][30 30 30][40 40 40]]
YY 矩阵的形状: (4, 3)

结果分析:

  • XX 矩阵的构建meshgrid 将原始的 x 向量 [1, 2, 3] 水平地复制了 len(y) 次(也就是4次),像叠煎饼一样垂直叠起来,形成一个 (4, 3) 的矩阵。所以,XX 的每一行都是 [1, 2, 3]
  • YY 矩阵的构建meshgrid 将原始的 y 向量 [10, 20, 30, 40] 垂直地复制了 len(x) 次(也就是3次),像手风琴一样水平拉开,形成一个 (4, 3) 的矩阵。所以,YY 的每一列都是 [10, 20, 30, 40]

最关键的一点是:现在 XXYY 在相同位置 (i, j) 上的值,正好对应了我们网格中第 i 行、第 j 列那个点的坐标!

例如,我们想找网格上第2行(索引为1)、第3列(索引为2)的那个点:

  • XX[1, 2] 的值是 3
  • YY[1, 2] 的值是 20
  • 所以这个点的坐标就是 (3, 20),和我们手动列出的一模一样!

三、为什么它如此有用?——矢量化计算

meshgrid 最大的优势在于它能让我们避免使用缓慢的 Python for 循环,而是利用 NumPy 的**矢量化计算(Vectorization)**能力,对整个网格进行一次性、高性能的计算。

应用场景:计算二维函数 z = sin(x) + cos(y) 在整个网格上的值。

方法一:使用 for 循环(效率低)

z_loop = np.zeros_like(XX, dtype=float) # 创建一个和XX形状相同的零矩阵for i in range(XX.shape[0]): # 遍历行for j in range(XX.shape[1]): # 遍历列z_loop[i, j] = np.sin(XX[i, j]) + np.cos(YY[i, j])# print("使用循环计算的结果:\n", z_loop)

这种方法非常直观,但当网格很大时,嵌套的Python循环会变得非常慢。

方法二:使用 meshgrid 和矢量化计算(高效)

# 因为 XX 和 YY 的形状完全相同,我们可以直接对它们进行数学运算
# NumPy 会自动对矩阵中的每一个元素执行操作
Z_vectorized = np.sin(XX) + np.cos(YY)# print("使用矢量化计算的结果:\n", Z_vectorized)

这一行代码就完成了和上面两层for循环完全一样的工作!它直接在C语言层面进行计算,速度比Python循环快几个数量级。

这就是 meshgrid 的威力所在:它为矢量化计算搭建了舞台。

四、进阶用法

1. 绘制三维曲面和等高线图

在数据可视化领域,尤其是在使用 matplotlib 库时,meshgrid 是不可或缺的。当你需要绘制一个三维曲面 z = f(x, y) 时,你需要提供 x, y, z 的坐标。这里的 xy 就必须是 meshgrid 生成的二维坐标矩阵。

import matplotlib.pyplot as pltx_surf = np.linspace(-5, 5, 100)
y_surf = np.linspace(-5, 5, 100)XX_surf, YY_surf = np.meshgrid(x_surf, y_surf)
Z_surf = np.sinc(np.sqrt(XX_surf**2 + YY_surf**2)) # 计算一个二维sinc函数fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(XX_surf, YY_surf, Z_surf, cmap='viridis')
plt.title("3D Surface Plot using meshgrid")
plt.show()
2. indexing 参数

meshgrid 有一个重要的参数 indexing,它有两个值:'xy' (默认值) 和 'ij'

  • indexing='xy'(笛卡尔坐标系索引):

    • 输出矩阵的形状是 (len(y), len(x))
    • XX 的行是 x 的拷贝,YY 的列是 y 的拷贝。
    • 这种方式最符合绘图和几何直觉。我们上面的所有例子都使用这种默认方式。
  • indexing='ij'(矩阵索引):

    • 输出矩阵的形状是 (len(x), len(y))
    • XX 的列是 x 的拷贝,YY 的行是 y 的拷贝。基本上是 'xy' 模式结果的转置。
    • 这种方式在进行纯粹的矩阵和数组运算时可能更自然。
XX_ij, YY_ij = np.meshgrid(x, y, indexing='ij')print("XX 矩阵 (indexing='ij'):\n", XX_ij)
print("XX_ij 的形状:", XX_ij.shape)
print("-" * 20)
print("YY 矩阵 (indexing='ij'):\n", YY_ij)
print("YY_ij 的形状:", YY_ij.shape)

输出:

XX 矩阵 (indexing='ij'):[[1 1 1 1][2 2 2 2][3 3 3 3]]
XX_ij 的形状: (3, 4)
--------------------
YY 矩阵 (indexing='ij'):[[10 20 30 40][10 20 30 40][10 20 30 40]]
YY_ij 的形状: (3, 4)

可以看到,输出矩阵的形状和值的排布都发生了变化。了解这个参数对于避免在复杂计算中出错非常重要。

总结

  1. 核心功能np.meshgrid 从一维的坐标轴向量生成二维(或多维)的坐标网格矩阵。
  2. 主要目的:为矢量化计算服务,让你能够对整个网格上的所有点进行快速、高效的并行计算,避免使用慢速的Python循环。
  3. 经典应用:计算二维/三维函数在网格上的值、生成数据用于绘制等高线图和三维表面图。
  4. 注意事项:留意 indexing 参数 ('xy' vs 'ij'),确保它符合你的计算或绘图需求。
http://www.dtcms.com/a/306886.html

相关文章:

  • C++ Qt网络编程实战:跨平台TCP调试工具开发
  • 基于SpringBoot+MyBatis+MySQL+VUE实现的便利店信息管理系统(附源码+数据库+毕业论文+远程部署)
  • 虚幻基础:模型碰撞体
  • [Qt]QString 与Sqlite3 字符串互动[汉字不乱码]
  • C#垃圾回收机制:原理与实践
  • PyTorch 生态四件套:从图片、视频到文本、语音的“开箱即用”实践笔记
  • 电子电气架构 --- 汽车电子电气EEA架构开发流程
  • 通义万相文生图模型wan2.2-t2i-flash和wan2.2-t2i-plus全维度深度对比
  • Java试题-选择题(1)
  • 【C++】适配器模式手搓STL的stack和queue
  • LeetCode Hot 100:15. 三数之和
  • Nuxt3 全栈作品【通用信息管理系统】角色管理(含配置权限 -- 菜单权限 vs 操作权限)
  • 差分数组前缀和优化,降低时间复杂度
  • vue+elementui+vueCropper裁剪上传图片背景颜色为黑色解决方案
  • ‌我的第一个开源项目:跃动的心
  • 物流分拣漏检率↓78%!陌讯动态光流算法在包裹移动识别的技术突破
  • GCC链接技术深度解析:性能与空间优化
  • [mcp: McpSchema]-源码分析
  • 第1课:向量与矩阵运算
  • 搭建实时足球比分系统从零到一的实战指南
  • Day 4-1: 机器学习算法全面总结
  • 全新AI工具小程序源码 全开源(源码下载)
  • 深入浅出:在 Spring Boot 中构建实时应用 - 全面掌握 WebSocket
  • 解决 Docker 报错 “exec: no such file or directory”
  • 文件权限值的表示方法
  • PHP/Java/Python实现:如何有效防止恶意文件上传
  • Go 语言make函数
  • 输电线路绝缘子泄漏电流在线监测装置的技术解析与应用价值
  • Python读取获取波形图波谷/波峰
  • Directory Opus 使用优化