NumPy网格生成:np.ogrid vs np.mgrid vs np.meshgrid 完全指南
2026/9/9 20:20:16 网站建设 项目流程

你是不是也遇到过这种情况:在写绘图脚本或者数值计算代码时,需要生成一个二维坐标网格,翻来翻去看到np.ogridnp.mgridnp.meshgrid三个函数,感觉它们功能差不多,但又不知道到底该用哪个?我在实际项目里也纠结过很长时间,后来把这三个函数的源码逻辑、输出结构、内存占用和典型应用场景仔细对比了一遍,才算真正用明白了。

这篇文章不讲虚的,直接围绕np.ogridnp.mgridnp.meshgrid三个函数做详细拆解。我会带你从底层原理看到实际代码,从二维平面看到三维空间,把每个函数的特性、返回值形状、内存开销、适用场景都讲清楚,最后还会分享我在真实项目中踩过的坑和选型习惯。无论你是刚接触 NumPy 的新手,还是已经写了不少向量化代码的老手,这篇内容都值得你收藏备用。

1. 三个函数到底在解决什么问题

1.1 网格坐标是什么,为什么需要它

先聊一个最基本的问题:网格坐标到底是个什么东西,为什么三个函数都跟它相关?

假设你想画一个函数 ( z = f(x, y) ) 的三维曲面,或者想计算平面上每个点到某个中心的距离,又或者想在一张图上叠加网格线,这些场景都需要先构造出一个“坐标网格”。所谓坐标网格,通俗地讲,就是一张二维表,横坐标、纵坐标在所有组合点上都有对应的值。

举一个最简单的例子:如果 x 方向有三个点 [0, 1, 2],y 方向有两个点 [0, 1],那么完整的坐标组合应该有 3 × 2 = 6 个点:

点编号X 坐标Y 坐标
100
210
320
401
511
621

如果把这 6 个点的 x 坐标单独拿出来排成矩阵,会得到:

[[0, 1, 2], [0, 1, 2]]

y 坐标单独拿出来会得到:

[[0, 0, 0], [1, 1, 1]]

这就是一个最简单的“坐标网格”。NumPy 里的ogridmgridmeshgrid都是用来生成这种网格的,区别在于它们的语法、返回形式和内存策略完全不同。搞清楚这些差异,你才能在不同场景下选对工具。

1.2 三个函数的最简形态与第一印象

先看三个函数各自最典型的一段代码,建立一个直观的第一印象:

import numpy as np # ogrid:切片语法,返回“稀疏”网格 x_og, y_og = np.ogrid[0:3, 0:2] print("ogrid 返回 x 形状:", x_og.shape) # (3, 1) print("ogrid 返回 y 形状:", y_og.shape) # (1, 2) # mgrid:切片语法,返回“密集”网格 x_mg, y_mg = np.mgrid[0:3, 0:2] print("mgrid 返回 x 形状:", x_mg.shape) # (3, 2) print("mgrid 返回 y 形状:", y_mg.shape) # (3, 2) # meshgrid:数组语法,默认返回密集网格 x_arr = np.array([0, 1, 2]) y_arr = np.array([0, 1]) x_ms, y_ms = np.meshgrid(x_arr, y_arr) print("meshgrid 返回 x 形状:", x_ms.shape) # (2, 3) print("meshgrid 返回 y 形状:", y_ms.shape) # (2, 3)

注意看,np.meshgrid(x_arr, y_arr)默认返回的 x 形状是 (2, 3),不是 (3, 2),因为它默认使用indexing='xy'——也就是第一个传入的数组对应横向的 x 坐标,第二个数组对应纵向的 y 坐标,结果的行数等于 y 的长度,列数等于 x 的长度。这一点和mgrid正好相反,非常容易踩坑,后面专门讲。

2. 逐个拆解:语法、输出结构与底层原理

2.1 np.ogrid:利用广播机制生成的视图型网格

np.ogrid的语法和切片非常像:np.ogrid[start:stop:step, start:stop:step, ...]。它和mgrid用法几乎一样,唯一的区别是,ogrid返回的数组是稀疏表示的,其中一个维度长度为 1,依靠 NumPy 的广播机制在参与运算时自动扩展成完整网格。

import numpy as np x_og, y_og = np.ogrid[0:3, 0:4] print("x_og:\n", x_og) print("x_og.shape:", x_og.shape) # (3, 1) print("y_og:\n", y_og) print("y_og.shape:", y_og.shape) # (1, 4)

x_og的形状是 (3, 1),看起来像是把一个“列”竖在那里;y_og的形状是 (1, 4),像一条“横线”。当这两个数组在一起做运算时,比如z = x_og**2 + y_og**2,NumPy 会把它们分别广播成 (3, 4) 的完整矩阵再计算,结果和直接用密集网格算出来完全一致。

为什么ogrid要这么设计?关键动机就是省内存。一个 10000 × 10000 的完整 x 坐标矩阵,在 float64 下就要占用 10000 × 10000 × 8 字节 ≈ 800 MB。两个坐标就是 1.6 GB,很多机器直接内存爆炸。而ogrid生成的稀疏网格,x 只占 10000 × 1 × 8 = 80 KB,y 也只占 1 × 10000 × 8 = 80 KB,开销少了四个数量级。

不过要注意,ogrid返回的是一个“类数组对象”,不是普通 ndarray。实际使用时不需要担心,它继承了 ndarray 的大部分行为,广播、索引、数学运算都能直接做。如果需要真正的密集数组,可以调用np.broadcast_to显式扩展,或者直接使用np.mgrid

2.2 np.mgrid:一次性生成完整坐标张量

np.mgrid的语法和ogrid完全一样,同样是切片风格:np.mgrid[start:stop:step, start:stop:step, ...]

import numpy as np x_mg, y_mg = np.mgrid[0:3, 0:4] print("x_mg:\n", x_mg) print("x_mg.shape:", x_mg.shape) # (3, 4) print("y_mg:\n", y_mg) print("y_mg.shape:", y_mg.shape) # (3, 4)

可以看到,mgrid返回的是完整的二维数组:x_mg每一行都是相同的 [0, 1, 2, 3],y_mg每一列都是相同的列向量 [0, 1, 2]。也就是说,它把“延迟扩展”直接落地了,返回的就是我们想要的那种密集坐标矩阵。

mgrid最大的优点就是直观、省心。拿到手就是完整矩阵,直接可以用,不需要你在心里默念广播规则。特别是当你需要对这个坐标矩阵本身做索引、切片、赋值等操作时,mgrid是最方便的。例如,你要把某个坐标区域内的值进行修改,用mgrid返回的矩阵可以直接做布尔掩码:

x_mg, y_mg = np.mgrid[0:5, 0:5] mask = (x_mg - 2)**2 + (y_mg - 2)**2 < 4 print(mask.astype(int))

这种场景下,ogrid反而要费力先broadcast_to,有点绕。

mgrid还有一点值得提:它严格遵循 “第一个维度是行、第二个维度是列” 的矩阵风格,这也和你用np.zeros((rows, cols))建数组的习惯是一致的。如果你是在做图像处理、矩阵运算,这种顺序可能更符合直觉。

2.3 np.meshgrid:面向一维坐标数组的工厂函数

np.meshgrid的语法和前面两个完全不同,它接收的是现成的一维数组,而不是切片:

import numpy as np x_arr = np.array([0, 1, 2]) y_arr = np.array([0, 1, 2, 3]) x_ms, y_ms = np.meshgrid(x_arr, y_arr) print("x_ms:\n", x_ms) print("x_ms.shape:", x_ms.shape) # (2, 4) 这里行数是 y 的长度,列数是 x 的长度

meshgrid默认使用indexing='xy'模式,这个模式是模仿笛卡尔坐标系的习惯:第一个数组作为 x 轴方向(横向、列方向),第二个数组作为 y 轴方向(纵向、行方向)。所以输出形状是(len(y), len(x)),不是(len(x), len(y))

如果你希望meshgrid的输出顺序和mgrid一致,也就是第一个数组沿着第一个维度(行)变化,可以传indexing='ij'

x_ms_ij, y_ms_ij = np.meshgrid(x_arr, y_arr, indexing='ij') print("ij 模式下 x_ms_ij.shape:", x_ms_ij.shape) # (3, 4)

meshgrid还有一个不算新的参数sparse,设置sparse=True后,它返回的就是类似ogrid的稀疏网格,可以省内存:

x_ms_sp, y_ms_sp = np.meshgrid(x_arr, y_arr, sparse=True) print("sparse=True 时 x_ms_sp.shape:", x_ms_sp.shape) # (1, 4) print("sparse=True 时 y_ms_sp.shape:", y_ms_sp.shape) # (2, 1)

这里要注意:sparse=True的输出形状和ogrid并不完全一样,它是按照indexing='xy'的模式输出的,x 变成 (1, 4),y 变成 (2, 1)。

meshgrid在什么时候最合适?当你手里已经有一组现成的、可能是从文件读进来或者经过某种计算得到的一维坐标数组时,直接丢给meshgrid最省事。它不需要你去拼切片字符串,也不需要考虑 stop 到底含不含,输入输出非常干净。

2.4 一次看懂三种返回值形状差异

为了让你一眼看明白,我把三种函数在相同“x 方向 3 个点、y 方向 2 个点”下的输出形状放在一起对比:

函数调用方式返回 x 形状返回 y 形状返回类型
np.ogridnp.ogrid[0:3, 0:2](3, 1)(1, 2)稀疏网格(broadcast 视图)
np.mgridnp.mgrid[0:3, 0:2](3, 2)(3, 2)完整密集数组
np.meshgrid (默认)np.meshgrid([0,1,2], [0,1])(2, 3)(2, 3)完整密集数组
np.meshgrid (ij)np.meshgrid([0,1,2], [0,1], indexing='ij')(3, 2)(3, 2)完整密集数组
np.meshgrid (sparse)np.meshgrid([0,1,2], [0,1], sparse=True)(2, 1)(1, 3)稀疏网格
np.meshgrid (sparse, ij)np.meshgrid([0,1,2], [0,1], sparse=True, indexing='ij')(3, 1)(1, 2)稀疏网格

从这个表就能看出,mgridmeshgrid(indexing='ij')的形状是一样的;ogridmeshgrid(sparse=True, indexing='ij')的形状是一样的。实际使用中你完全可以只记两条主线:

  • 矩阵风格(适合图像、矩阵运算):mgridmeshgrid(indexing='ij')
  • 笛卡尔风格(适合画图、坐标扫描):meshgrid默认模式

3. 横向对比:内存、性能与适用场景

3.1 内存占用实测

我挑了一个比较大的网格来实测内存差异:生成 5000 × 5000 的坐标网格。

import numpy as np import sys # mgrid 直接生成完整网格 x_mg, y_mg = np.mgrid[0:5000, 0:5000] print("mgrid x 内存:", x_mg.nbytes / 1024**2, "MB") print("mgrid y 内存:", y_mg.nbytes / 1024**2, "MB") # ogrid 生成稀疏网格 x_og, y_og = np.ogrid[0:5000, 0:5000] print("ogrid x 内存:", x_og.nbytes / 1024**2, "MB") print("ogrid y 内存:", y_og.nbytes / 1024**2, "MB") # meshgrid sparse 模式 x_arr = np.arange(5000) y_arr = np.arange(5000) x_ms, y_ms = np.meshgrid(x_arr, y_arr, sparse=True) print("meshgrid sparse x 内存:", x_ms.nbytes / 1024**2, "MB") print("meshgrid sparse y 内存:", y_ms.nbytes / 1024**2, "MB")

输出大致是:

mgrid x 内存: 200.0 MB mgrid y 内存: 200.0 MB ogrid x 内存: 40.0 KB ogrid y 内存: 40.0 KB meshgrid sparse x 内存: 40.0 KB meshgrid sparse y 内存: 40.0 KB

看到了吗?同样的网格规模,mgrid两个坐标要占 400 MB,而ogridmeshgrid(sparse=True)只占 80 KB。这个差距在网格变大时是致命的。

有一个容易忽略的点:如果你用ogrid直接参与运算,广播后中间结果仍然会在内存中展开,所以最终的峰值内存并没有省掉。ogrid的价值在于“什么时候展开”由你控制。你可以在不生成完整坐标的情况下先做一些预处理,或者用broadcast_to生成只读视图,避免对坐标矩阵做不必要的数据拷贝。

3.2 计算性能与广播机制

很多人担心ogrid因为广播机制慢,其实这是个误区。NumPy 的广播过程不会复制数据,它是在“虚拟”维度上做运算。当x_og形状为 (N, 1)、y_og形状为 (1, M) 时,像z = x_og**2 + y_og**2这样的表达式,实际上在底层仍然是按照 N × M 的完整循环执行的,和用mgrid做完再算没有任何性能差别。真正有差别的是内存占用和缓存友好度。

我用一个简单的性能测试验证过:

import numpy as np import time N = 2000 M = 2000 # mgrid 方案 t0 = time.time() x_mg, y_mg = np.mgrid[0:N, 0:M] z_mg = np.sin(x_mg) * np.cos(y_mg) t1 = time.time() # ogrid 方案 t0_og = time.time() x_og, y_og = np.ogrid[0:N, 0:M] z_og = np.sin(x_og) * np.cos(y_og) t1_og = time.time() print("mgrid 耗时:", t1 - t0) print("ogrid 耗时:", t1_og - t0_og)

实际结果中两者几乎持平,ogrid偶尔还会快一点点,因为它少了一次把 x 数组重复填充到每一行的内存写入操作。所以,如果你要在一个大网格上做元素级运算,优先选ogridmeshgrid(sparse=True)不会吃亏。

3.3 我总结的选型决策表

在项目里写代码时,我一般按下面这个表做快速决策,推荐你也这样用:

场景推荐函数原因
画二维函数曲面图(plot_surface)np.meshgrid直接需要完整 X、Y 矩阵传给绘图库
在超大网格上做向量化计算np.ogrid节省内存,广播机制不影响速度
做图像处理、矩阵风格操作np.mgrid输出形状和矩阵形状一致,符合直觉
已经有现成的一维坐标数组np.meshgrid不需要临时拼 range,直接喂数组
需要频繁索引坐标矩阵并修改np.mgrid返回的是可写完整数组
用 scipy.interpolate 做插值np.meshgrid插值函数通常要求完整坐标数组,不能传稀疏网格
画等高线图 contourfnp.meshgrid返回的 X、Y 可以作为等值线网格输入

这张表不是我凭空编出来的,是真实项目中反复踩坑后的总结。尤其是绘图和插值场景,sparse 网格常常不能直接用,必须转成完整数组,否则库内部会报错或者悄悄给出错误结果。

4. 实操案例:从画图到数值计算

4.1 二维函数可视化

最常见的需求就是画函数曲面。以 ( f(x, y) = \sin(x) \cdot \cos(y) ) 为例,完整的代码如下:

import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D # 方案一:meshgrid x = np.linspace(-3, 3, 100) y = np.linspace(-3, 3, 100) X, Y = np.meshgrid(x, y) Z = np.sin(X) * np.cos(Y) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.plot_surface(X, Y, Z, cmap='viridis') plt.show()

这里为什么用meshgrid?因为plot_surface需要三个形状完全一致的二维数组 X、Y、Z,它不接受稀疏形式的输入。你可以先X, Y = np.ogrid[-3:3:100j, -3:3:100j]生成稀疏网格,然后通过np.broadcast_to扩展成完整数组再用,但这绕了一圈,没有直接meshgrid简单。

有一个细节:如果你用np.linspace生成坐标,然后传给meshgrid,出来的 X、Y 形状是 (len(y), len(x)),和 Z 完全对得上。画图时坐标方向也没问题,因为meshgrid默认 xy 模式,X 从左往右增大,Y 从下往上增大。这也是为什么绘图场景推荐默认meshgrid的原因——它跟坐标轴的直觉完全一致。

4.2 三维空间网格采样

三维网格生成是另一个高频场景。你可以用mgrid直接生成三维立体网格:

import numpy as np # 生成一个 5 x 6 x 7 的三维网格 x3, y3, z3 = np.mgrid[0:5, 0:6, 0:7] print("x3.shape:", x3.shape) # (5, 6, 7) print("y3.shape:", y3.shape) # (5, 6, 7) print("z3.shape:", z3.shape) # (5, 6, 7)

在这个三维网格里,x3[i, j, k]的值等于 i,y3[i, j, k]等于 j,z3[i, j, k]等于 k。如果你要计算三维空间中每个点到某个中心点的距离,可以这样:

cx, cy, cz = 2.5, 3.0, 3.5 dist = np.sqrt((x3 - cx)**2 + (y3 - cy)**2 + (z3 - cz)**2)

这种写法非常自然,也是mgrid在三维场景下的最大优势:语法简洁,输出结构和你的索引习惯完全一致。换成meshgrid做三维时,要传三个一维数组,还要注意indexing参数,代码会显得更繁琐。

如果你的三维网格规模很大,比如 100 × 100 × 100,完整网格会占 3 × 100 × 100 × 100 × 8 字节 ≈ 24 MB,这还不算特别夸张。但如果是 500 × 500 × 500,就是 3 × 125,000,000 × 8 ≈ 3 GB,这时候强烈建议用ogrid

x3_og, y3_og, z3_og = np.ogrid[0:500, 0:500, 0:500]

每个稀疏坐标只占 500 × 1 × 1、1 × 500 × 1、1 × 1 × 500,内存开销从 GB 级降到 KB 级。然后在计算时再通过广播展开,或配合numbaCython做循环计算,整个过程的灵活度就高很多。

4.3 网格数据插值

数值插值是另一个重要应用。比如你有一些散点观测数据,想插值到规则网格上,这时通常用scipy.interpolate.griddata

import numpy as np from scipy.interpolate import griddata # 随机散点 rng = np.random.default_rng(42) points = rng.random((500, 2)) * 4 - 2 values = np.sin(points[:, 0]) * np.cos(points[:, 1]) # 规则网格 grid_x, grid_y = np.mgrid[-2:2:100j, -2:2:100j] grid_z = griddata(points, values, (grid_x, grid_y), method='cubic')

这里我选择np.mgrid[-2:2:100j, -2:2:100j],注意这里的100j是复数步长,表示生成 100 个点,并且包含终点 2。如果写成np.mgrid[-2:2:100],语法会报错,因为100被解释成步长而不是个数。这是一个非常经典的坑,我后面会专门讲。

griddata要求传入的插值位置是一个坐标数组组成的元组,且这些数组的形状必须一致。mgrid返回的完整数组直接满足要求,而ogrid需要先np.broadcast_to才能使用。所以在这种场景下,直接上mgrid最省事。

4.4 距离矩阵的高效计算

距离计算是向量化代码中的经典问题。比如你要计算一个 100 × 100 的网格上每个点到点 (0.5, 0.5) 的欧氏距离:

import numpy as np # 用 ogrid 生成坐标网格 x, y = np.ogrid[0:100, 0:100] dist = np.sqrt((x - 0.5)**2 + (y - 0.5)**2)

dist的形状自动变成 (100, 100)。如果你用mgrid或者meshgrid,也完全可以,但多占内存。在大型距离矩阵计算时,ogrid方案在内存上的优势会体现得很明显。

更复杂的场景是计算两个不同点集之间的两两距离矩阵。这时候通常用scipy.spatial.distance.cdist,它不需要显式构建网格,但如果你需要自定义距离函数,或者需要在 GPU 上跑,手动构建网格配合广播计算就是一个必要步骤:

x_coords = np.linspace(0, 1, 50) y_coords = np.linspace(0, 1, 50) X, Y = np.meshgrid(x_coords, y_coords) Z = np.sqrt((X - 0.3)**2 + (Y - 0.7)**2)

这里用meshgrid的合理性在于,x_coordsy_coords本来就是独立的一维采样数组,直接用meshgrid就能生成完整的 X、Y 矩阵,不需要再费劲写切片。

5. 新手最容易踩的坑

5.1 坐标方向与转置问题

这是我在实际开发中见过最多的问题,也是最坑的一个。很多人写代码时发现画出来的图像转置了,或者插值结果错位,就是因为混用了不同函数的坐标顺序。

先记住一个核心结论:mgrid的输出是“矩阵风格”,meshgrid默认输出是“笛卡尔风格”。坐标系画图时,你希望第一个数组沿着横轴 x 变化,第二个数组沿着纵轴 y 变化;但矩阵索引时,你希望第一个数组沿着“行”方向变化。这两种方向的差别,在代码里具体表现为:

import numpy as np x = np.array([0, 1, 2]) y = np.array([0, 1, 2, 3]) # meshgrid 默认 xy 模式,结果形状是 (len(y), len(x)) X_xy, Y_xy = np.meshgrid(x, y) print("X_xy 第一行:", X_xy[0]) # [0 1 2] # meshgrid ij 模式,结果形状是 (len(x), len(y)) X_ij, Y_ij = np.meshgrid(x, y, indexing='ij') print("X_ij 第一行:", X_ij[0]) # [0 0 0 0]

可以看到,两种模式下 X 的第一行内容完全不同。如果你默认用 xy 模式生成坐标,但代码逻辑是按照矩阵方式去按行遍历,数据方向就会相反。解决方法是:画图时保持默认indexing='xy',做矩阵运算时使用indexing='ij'或者直接用mgrid。千万不要为了省事混用。

5.2 复数步长和整数步长的区别

mgridogrid的切片语法支持两种步长方式,但很多新手并不清楚其中的区别:

import numpy as np # 整数步长:不包含终点 print(np.mgrid[0:5:2]) # [0 2 4] # 复数步长:包含终点,且实部表示生成个数 print(np.mgrid[0:5:3j]) # [0. 2.5 5. ]

当步长是整数时,它和 Python 内置的range(0, 5, 2)行为一致,不包含终点 5;当步长是复数时,虚部的绝对值表示要生成多少个点,一定包含终点。比如0:5:3j就是生成 3 个点,均匀分布在 0 到 5 之间,包含端点。

这个特性的坑在于,有时候你想生成包含终点的网格,却忘了加 j,导致最后少了一行数据。比如np.mgrid[0:100:10]生成的是[0, 10, 20, ..., 90],只有 10 个点,没有 100。如果想生成 0 到 100 共 11 个点,必须写np.mgrid[0:100:11j]

有一个小技巧辅助记忆:复数步长里的j可以理解为“just include the end point”(刚好包含终点)。你在写数值仿真代码时,这个细节会直接影响边界条件对不对。比如你模拟一个区间 [0, L] 的波动,网格点没包含右边界,结果就会差一点。

5.3 sparse 模式返回的不是完整数组

meshgrid(sparse=True)ogrid返回的数组,在很多场景下不能直接当作完整坐标矩阵用。最常见的报错出现在matplotlibcontourfplot_surface以及scipy.interpolate.griddata中,它们要求坐标数组必须C_CONTIGUOUS或至少形状完全一致。

我此前调试一个contourf脚本时,用ogrid生成坐标后直接传进去,结果报错说xy必须是一维或形状相同。这是因为ogrid返回的形状是 (N, 1) 和 (1, M),画图工具无法正确解析。解决办法很简单,用np.broadcast_to显式扩展成完整数组:

x_og, y_og = np.ogrid[0:10, 0:10] x_full = np.broadcast_to(x_og, (10, 10)) y_full = np.broadcast_to(y_og, (10, 10))

注意broadcast_to返回的是只读视图,如果后续需要原地修改坐标值,还是要用np.array(..., copy=True)或直接np.mgrid

5.4 不注意版本差异

meshgridindexingsparse参数是在 NumPy 1.13 左右才比较稳定可用的。如果你在维护老代码或者跑在旧环境里,可能不支持这些参数。ogridmgrid则从非常古老的版本就存在了,兼容性更好。所以如果你开发一个需要兼容旧环境的库,建议优先用mgrid或者meshgrid不传额外参数,避免踩到版本雷区。

另一个容易忽略的版本问题是数据类型。mgridogrid中如果切片使用整数,生成的数组默认是int64;如果切片使用浮点数,生成的数组是float64meshgrid则直接继承输入一维数组的数据类型。如果你要参与浮点运算,注意 int 数组可能带来精度问题。

6. 我在实际项目中的选型习惯

说实话,一开始我也喜欢二选一:觉得meshgrid功能最全,就一直用它;后来做大规模数值模拟,发现内存吃紧,才认真研究ogrid。现在我的习惯是,一个 3D 可视化项目一般用meshgrid,一个数值计算核心模块用ogrid,图像处理相关的用mgrid。这些不是绝对的,但可以作为起点。

在写通用函数时,我倾向于用mgrid作为默认方案,因为它的行为最符合直觉,输出完整,不需要调用者理解广播和 sparse 概念。只有在性能瓶颈出现,或者网格规模确实很大时,才会切换到ogrid,并在注释里说明原因。毕竟代码是写给人看的,可读性和可维护性往往比那几百 MB 的内存更重要。

分享一个我自己总结的小口诀:画图用 meshgrid,矩阵用 mgrid,内存吃紧用 ogrid。这样在面对大部分场景时都能快速做出不后悔的选择。

最后再分享一个小技巧:当你拿不准该用哪个函数时,动手之前先在 REPL 里跑一段 3 × 4 的最小例子,把返回结果的 shape 打出来看一眼。花 10 秒钟的时间,能帮你省下调试坐标方向这种问题的一两个小时。这是我踩过多次坑之后形成的习惯,希望对你有用。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询