Python/NumPy 中 meshgrid 的用途是什么?
What is the purpose of meshgrid in Python / NumPy?
谁能给我解释一下 Numpy 中 meshgrid
函数的用途是什么?我知道它会创建某种用于绘图的坐标网格,但我看不到它的直接好处。
我正在向 Sebastian Raschka 学习 "Python Machine Learning",他正在使用它来绘制决策边界。请参见输入 11 here.
我也试过官方文档中的这段代码,但同样,输出对我来说并没有真正意义。
x = np.arange(-5, 5, 1)
y = np.arange(-5, 5, 1)
xx, yy = np.meshgrid(x, y, sparse=True)
z = np.sin(xx**2 + yy**2) / (xx**2 + yy**2)
h = plt.contourf(x,y,z)
如果可能的话,请给我看很多真实世界的例子。
假设你有一个函数:
def sinus2d(x, y):
return np.sin(x) + np.sin(y)
并且您想要,例如,查看它在 0 到 2*pi 范围内的样子。你会怎么做? np.meshgrid
进来了:
xx, yy = np.meshgrid(np.linspace(0,2*np.pi,100), np.linspace(0,2*np.pi,100))
z = sinus2d(xx, yy) # Create the image on this grid
这样的情节看起来像:
import matplotlib.pyplot as plt
plt.imshow(z, origin='lower', interpolation='none')
plt.show()
所以np.meshgrid
只是方便而已。原则上同样可以通过以下方式完成:
z2 = sinus2d(np.linspace(0,2*np.pi,100)[:,None], np.linspace(0,2*np.pi,100)[None,:])
但是你需要知道你的尺寸(假设你有两个以上......)和正确的广播。 np.meshgrid
为您完成这一切。
此外,meshgrid 还允许您删除坐标和数据,例如,如果您想要进行插值但排除某些值:
condition = z>0.6
z_new = z[condition] # This will make your array 1D
那么你现在如何进行插值?您可以将 x
和 y
提供给像 scipy.interpolate.interp2d
这样的插值函数,因此您需要一种方法来知道删除了哪些坐标:
x_new = xx[condition]
y_new = yy[condition]
然后您仍然可以使用 "right" 坐标进行插值(尝试不使用 meshgrid,您将有很多额外的代码):
from scipy.interpolate import interp2d
interpolated = interp2d(x_new, y_new, z_new)
并且原始网格允许您再次在原始网格上进行插值:
interpolated_grid = interpolated(xx[0], yy[:, 0]).reshape(xx.shape)
这些只是我使用 meshgrid
的一些示例,可能还有更多。
meshgrid
的目的是用 x 值数组和 y 值数组创建矩形网格。
因此,例如,如果我们想要创建一个网格,在 x 和 y 方向上,我们在 0 到 4 之间的每个整数值处都有一个点。要创建矩形网格,我们需要 x
和 y
点的每个组合。
这将是 25 分,对吧?因此,如果我们想为所有这些点创建一个 x 和 y 数组,我们 可以 执行以下操作。
x[0,0] = 0 y[0,0] = 0
x[0,1] = 1 y[0,1] = 0
x[0,2] = 2 y[0,2] = 0
x[0,3] = 3 y[0,3] = 0
x[0,4] = 4 y[0,4] = 0
x[1,0] = 0 y[1,0] = 1
x[1,1] = 1 y[1,1] = 1
...
x[4,3] = 3 y[4,3] = 4
x[4,4] = 4 y[4,4] = 4
这将导致以下 x
和 y
矩阵,这样每个矩阵中对应元素的配对给出网格中某个点的 x 和 y 坐标。
x = 0 1 2 3 4 y = 0 0 0 0 0
0 1 2 3 4 1 1 1 1 1
0 1 2 3 4 2 2 2 2 2
0 1 2 3 4 3 3 3 3 3
0 1 2 3 4 4 4 4 4 4
然后我们可以绘制这些以验证它们是一个网格:
plt.plot(x,y, marker='.', color='k', linestyle='none')
显然,这变得非常乏味,尤其是对于大范围的 x
和 y
。相反,meshgrid
实际上可以为我们生成这个:我们必须指定的是唯一的 x
和 y
值。
xvalues = np.array([0, 1, 2, 3, 4]);
yvalues = np.array([0, 1, 2, 3, 4]);
现在,当我们调用 meshgrid
时,我们会自动获得之前的输出。
xx, yy = np.meshgrid(xvalues, yvalues)
plt.plot(xx, yy, marker='.', color='k', linestyle='none')
创建这些矩形网格对许多任务很有用。在您在 post 中提供的示例中,它只是一种在 x
和 y
的值范围内对函数 (sin(x**2 + y**2) / (x**2 + y**2)
) 进行采样的方法。
因为此函数已在矩形网格上采样,所以现在可以将此函数可视化为 "image"。
此外,现在可以将结果传递给需要矩形网格数据的函数(即 contourf
)
由微软提供 Excel:
其实np.meshgrid
的目的在文档中已经提到了:
Return coordinate matrices from coordinate vectors.
Make N-D coordinate arrays for vectorized evaluations of N-D scalar/vector fields over N-D grids, given one-dimensional coordinate arrays x1, x2,..., xn.
所以它的主要目的是创建一个坐标矩阵。
您可能刚刚问过自己:
为什么我们需要创建坐标矩阵?
你需要坐标矩阵 Python/NumPy 的原因是坐标与值之间没有直接关系,除非你的坐标从零开始并且是纯正整数。然后你可以只使用数组的索引作为索引。
但是,如果不是这种情况,您需要以某种方式将坐标与数据一起存储。这就是网格的用武之地。
假设你的数据是:
1 2 1
2 5 2
1 2 1
但是,每个值代表一个 3 x 2 公里的区域(水平 x 垂直)。假设你的原点是左上角,你想要代表你可以使用的距离的数组:
import numpy as np
h, v = np.meshgrid(np.arange(3)*3, np.arange(3)*2)
其中 v 是:
array([[0, 0, 0],
[2, 2, 2],
[4, 4, 4]])
和h:
array([[0, 3, 6],
[0, 3, 6],
[0, 3, 6]])
因此,如果您有两个索引,假设 x
和 y
(这就是为什么 meshgrid
的 return 值通常是 xx
或 xs
而不是 x
在这种情况下我选择 h
水平!)然后你可以得到点的 x 坐标,点的 y 坐标和那个点的值通过使用:
h[x, y] # horizontal coordinate
v[x, y] # vertical coordinate
data[x, y] # value
这使得跟踪坐标变得更加容易并且(更重要的是)您可以将它们传递给需要知道坐标的函数。
稍微长一点的解释
然而,np.meshgrid
本身并不经常直接使用,大多数人只是使用 similar 对象之一 np.mgrid
或 np.ogrid
。
这里 np.mgrid
代表 sparse=False
而 np.ogrid
代表 sparse=True
的情况(我指的是 np.meshgrid
的 sparse
论点)。请注意,两者之间存在显着差异
np.meshgrid
and np.ogrid
and np.mgrid
:前两个 returned 值(如果有两个或更多)被反转。通常这无关紧要,但您应该根据上下文给出有意义的变量名称。
例如,在二维网格和 matplotlib.pyplot.imshow
的情况下,将 return 的第一个 return 项目命名为 np.meshgrid
x
和第二个 y
而它是
np.mgrid
和 np.ogrid
.
相反
np.ogrid
和稀疏网格
>>> import numpy as np
>>> yy, xx = np.ogrid[-5:6, -5:6]
>>> xx
array([[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]])
>>> yy
array([[-5],
[-4],
[-3],
[-2],
[-1],
[ 0],
[ 1],
[ 2],
[ 3],
[ 4],
[ 5]])
如前所述,与 np.meshgrid
相比,输出是相反的,这就是为什么我将其解压缩为 yy, xx
而不是 xx, yy
:
>>> xx, yy = np.meshgrid(np.arange(-5, 6), np.arange(-5, 6), sparse=True)
>>> xx
array([[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]])
>>> yy
array([[-5],
[-4],
[-3],
[-2],
[-1],
[ 0],
[ 1],
[ 2],
[ 3],
[ 4],
[ 5]])
这看起来像坐标,特别是二维绘图的 x 和 y 线。
可视化:
yy, xx = np.ogrid[-5:6, -5:6]
plt.figure()
plt.title('ogrid (sparse meshgrid)')
plt.grid()
plt.xticks(xx.ravel())
plt.yticks(yy.ravel())
plt.scatter(xx, np.zeros_like(xx), color="blue", marker="*")
plt.scatter(np.zeros_like(yy), yy, color="red", marker="x")
np.mgrid
和dense/fleshed出格
>>> yy, xx = np.mgrid[-5:6, -5:6]
>>> xx
array([[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]])
>>> yy
array([[-5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5],
[-4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4],
[-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3],
[-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2],
[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
[ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4],
[ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]])
这里同样适用:输出与np.meshgrid
相反:
>>> xx, yy = np.meshgrid(np.arange(-5, 6), np.arange(-5, 6))
>>> xx
array([[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]])
>>> yy
array([[-5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5],
[-4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4],
[-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3],
[-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2],
[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
[ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4],
[ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]])
与ogrid
不同,这些数组包含所有 xx
和yy
坐标在-5 <= xx <= 5; -5 <= yy <= 5 格。
yy, xx = np.mgrid[-5:6, -5:6]
plt.figure()
plt.title('mgrid (dense meshgrid)')
plt.grid()
plt.xticks(xx[0])
plt.yticks(yy[:, 0])
plt.scatter(xx, yy, color="red", marker="x")
功能
它不仅限于 2D,这些函数适用于任意维度(好吧,在 Python 中为函数提供了最大数量的参数以及 NumPy 允许的最大维度数量):
>>> x1, x2, x3, x4 = np.ogrid[:3, 1:4, 2:5, 3:6]
>>> for i, x in enumerate([x1, x2, x3, x4]):
... print('x{}'.format(i+1))
... print(repr(x))
x1
array([[[[0]]],
[[[1]]],
[[[2]]]])
x2
array([[[[1]],
[[2]],
[[3]]]])
x3
array([[[[2],
[3],
[4]]]])
x4
array([[[[3, 4, 5]]]])
>>> # equivalent meshgrid output, note how the first two arguments are reversed and the unpacking
>>> x2, x1, x3, x4 = np.meshgrid(np.arange(1,4), np.arange(3), np.arange(2, 5), np.arange(3, 6), sparse=True)
>>> for i, x in enumerate([x1, x2, x3, x4]):
... print('x{}'.format(i+1))
... print(repr(x))
# Identical output so it's omitted here.
即使这些也适用于一维,但有两个(更常见的)一维网格创建函数:
除了start
和stop
参数外,它还支持step
参数(即使是表示步骤数的复杂步骤):
>>> x1, x2 = np.mgrid[1:10:2, 1:10:4j]
>>> x1 # The dimension with the explicit step width of 2
array([[1., 1., 1., 1.],
[3., 3., 3., 3.],
[5., 5., 5., 5.],
[7., 7., 7., 7.],
[9., 9., 9., 9.]])
>>> x2 # The dimension with the "number of steps"
array([[ 1., 4., 7., 10.],
[ 1., 4., 7., 10.],
[ 1., 4., 7., 10.],
[ 1., 4., 7., 10.],
[ 1., 4., 7., 10.]])
应用程序
您特意询问了用途,事实上,如果您需要坐标系,这些网格非常有用。
例如,如果您有一个计算二维距离的 NumPy 函数:
def distance_2d(x_point, y_point, x, y):
return np.hypot(x-x_point, y-y_point)
而您想知道每个点的距离:
>>> ys, xs = np.ogrid[-5:5, -5:5]
>>> distances = distance_2d(1, 2, xs, ys) # distance to point (1, 2)
>>> distances
array([[9.21954446, 8.60232527, 8.06225775, 7.61577311, 7.28010989,
7.07106781, 7. , 7.07106781, 7.28010989, 7.61577311],
[8.48528137, 7.81024968, 7.21110255, 6.70820393, 6.32455532,
6.08276253, 6. , 6.08276253, 6.32455532, 6.70820393],
[7.81024968, 7.07106781, 6.40312424, 5.83095189, 5.38516481,
5.09901951, 5. , 5.09901951, 5.38516481, 5.83095189],
[7.21110255, 6.40312424, 5.65685425, 5. , 4.47213595,
4.12310563, 4. , 4.12310563, 4.47213595, 5. ],
[6.70820393, 5.83095189, 5. , 4.24264069, 3.60555128,
3.16227766, 3. , 3.16227766, 3.60555128, 4.24264069],
[6.32455532, 5.38516481, 4.47213595, 3.60555128, 2.82842712,
2.23606798, 2. , 2.23606798, 2.82842712, 3.60555128],
[6.08276253, 5.09901951, 4.12310563, 3.16227766, 2.23606798,
1.41421356, 1. , 1.41421356, 2.23606798, 3.16227766],
[6. , 5. , 4. , 3. , 2. ,
1. , 0. , 1. , 2. , 3. ],
[6.08276253, 5.09901951, 4.12310563, 3.16227766, 2.23606798,
1.41421356, 1. , 1.41421356, 2.23606798, 3.16227766],
[6.32455532, 5.38516481, 4.47213595, 3.60555128, 2.82842712,
2.23606798, 2. , 2.23606798, 2.82842712, 3.60555128]])
如果通过密集网格而不是开放网格,输出将是相同的。 NumPys 广播使之成为可能!
让我们想象一下结果:
plt.figure()
plt.title('distance to point (1, 2)')
plt.imshow(distances, origin='lower', interpolation="none")
plt.xticks(np.arange(xs.shape[1]), xs.ravel()) # need to set the ticks manually
plt.yticks(np.arange(ys.shape[0]), ys.ravel())
plt.colorbar()
这也是 NumPys mgrid
和 ogrid
变得非常方便的时候,因为它允许您轻松更改网格的分辨率:
ys, xs = np.ogrid[-5:5:200j, -5:5:200j]
# otherwise same code as above
但是,由于 imshow
不支持 x
和 y
输入,因此必须手动更改刻度。如果它接受 x
和 y
坐标,那将非常方便,对吗?
用 NumPy 编写自然处理网格的函数很容易。此外,NumPy,SciPy,matplotlib 中有几个函数希望您在网格中传递。
我喜欢图片所以让我们探索一下 matplotlib.pyplot.contour
:
ys, xs = np.mgrid[-5:5:200j, -5:5:200j]
density = np.sin(ys)-np.cos(xs)
plt.figure()
plt.contour(xs, ys, density)
注意坐标是如何正确设置的!如果您只是传入 density
.
,情况就不同了
或者使用 astropy models 给出另一个有趣的例子(这次我不太关心坐标,我只是用它们来创建 一些 网格):
from astropy.modeling import models
z = np.zeros((100, 100))
y, x = np.mgrid[0:100, 0:100]
for _ in range(10):
g2d = models.Gaussian2D(amplitude=100,
x_mean=np.random.randint(0, 100),
y_mean=np.random.randint(0, 100),
x_stddev=3,
y_stddev=3)
z += g2d(x, y)
a2d = models.AiryDisk2D(amplitude=70,
x_0=np.random.randint(0, 100),
y_0=np.random.randint(0, 100),
radius=5)
z += a2d(x, y)
虽然那只是“为了外表”与功能模型和拟合相关的所有功能(例如scipy.interpolate.interp2d
,
scipy.interpolate.griddata
甚至在 Scipy 中使用 np.mgrid
) 显示示例,等等需要网格。其中大部分适用于开放网格和密集网格,但有些仅适用于其中之一。
meshgrid 有助于从两个一维数组创建一个矩形网格,该数组包含两个数组中的所有点对。
x = np.array([0, 1, 2, 3, 4])
y = np.array([0, 1, 2, 3, 4])
现在,如果您已经定义了一个函数 f(x,y) 并且您想要将此函数应用于数组 'x' 和 'y' 中所有可能的点组合,那么您可以这样做:
f(*np.meshgrid(x, y))
比如说,如果您的函数只生成两个元素的乘积,那么这就是笛卡尔乘积的实现方式,对大型数组非常有效。
引用自here
基本思路
给定可能的 x 值,xs
,(将它们视为绘图 x 轴上的刻度线)和可能的 y 值,ys
,meshgrid
生成相应的一组 (x, y) 网格点---类似于 set((x, y) for x in xs for y in yx)
。例如,如果 xs=[1,2,3]
和 ys=[4,5,6]
,我们将得到坐标集 {(1,4), (2,4), (3,4), (1,5), (2,5), (3,5), (1,6), (2,6), (3,6)}
.
Return 值的形式
但是meshgrid
returns的表示与上面的表达有两点不同:
首先,meshgrid
在二维数组中布置网格点:行对应不同的y值,列对应不同的x值---如在 list(list((x, y) for x in xs) for y in ys)
中,将给出以下数组:
[[(1,4), (2,4), (3,4)],
[(1,5), (2,5), (3,5)],
[(1,6), (2,6), (3,6)]]
第二个,meshgrid
returns x 和 y 坐标分别(即在两个不同的 numpy 二维数组中):
xcoords, ycoords = (
array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3]]),
array([[4, 4, 4],
[5, 5, 5],
[6, 6, 6]]))
# same thing using np.meshgrid:
xcoords, ycoords = np.meshgrid([1,2,3], [4,5,6])
# same thing without meshgrid:
xcoords = np.array([xs] * len(ys)
ycoords = np.array([ys] * len(xs)).T
注意,np.meshgrid
也可以生成更高维度的网格。给定 xs、ys 和 zs,您将返回 xcoords、ycoords、zcoords 作为 3d 数组。 meshgrid
还支持维度的反向排序以及结果的稀疏表示。
应用程序
为什么我们需要这种形式的输出?
在网格上的每个点应用函数:
一个动机是像 (+, -, *, /, **) 这样的二元运算符作为元素操作对 numpy 数组进行了重载。这意味着如果我有一个函数 def f(x, y): return (x - y) ** 2
适用于两个标量,我也可以将它应用于两个 numpy 数组以获得元素结果数组:例如f(xcoords, ycoords)
或 f(*np.meshgrid(xs, ys))
在上面的示例中给出以下内容:
array([[ 9, 4, 1],
[16, 9, 4],
[25, 16, 9]])
高维外积:我不确定这样的效率如何,但是你可以这样得到高维外积:np.prod(np.meshgrid([1,2,3], [1,2], [1,2,3,4]), axis=0)
.
matplotlib 中的等高线图: 我在调查 drawing contour plots with matplotlib for plotting decision boundaries 时遇到 meshgrid
。为此,您使用 meshgrid
生成一个网格,在每个网格点评估函数(例如,如上所示),然后将 xcoords、ycoords 和计算的 f 值(即 zcoords)传递给 contourf 函数。
简答
meshgrid
的目的是通过 C NumPy 库中的矢量化操作来帮助 replace Python loops(缓慢的解释代码)。
借自 this site.
x = np.arange(-4, 4, 0.25)
y = np.arange(-4, 4, 0.25)
X, Y = np.meshgrid(x, y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
meshgrid
用于创建 -4 和 +4 之间的坐标对,在 X 和 Y 的每个方向上增量为 0.25。然后使用每一对从中找到 R 和 Z。这种准备坐标“网格”的方法经常用于绘制 3D 表面或为 2D 表面着色。
详情:Python for-loop vs NumPy 向量运算
举一个更简单的例子,假设我们有两个值序列,
a = [2,7,9,20]
b = [1,6,7,9]
我们想对每对可能的值执行操作,一个取自第一个列表,一个取自第二个列表。我们还想存储结果。例如,假设我们想要获得每个可能对的值的总和。
缓慢费力的方法
c = []
for i in range(len(b)):
row = []
for j in range(len(a)):
row.append (a[j] + b[i])
c.append (row)
print (c)
结果:
[[3, 8, 10, 21],
[8, 13, 15, 26],
[9, 14, 16, 27],
[11, 16, 18, 29]]
Python是解释的,这些循环执行起来比较慢。
快速简便的方法
meshgrid
旨在从代码中删除循环。它 returns 两个数组(下面的 i 和 j)可以组合起来扫描所有现有的对:
i,j = np.meshgrid (a,b)
c = i + j
print (c)
结果:
[[ 3 8 10 21]
[ 8 13 15 26]
[ 9 14 16 27]
[11 16 18 29]]
引擎盖下的 Meshgrid
meshgrid
准备的两个数组是:
(array([[ 2, 7, 9, 20],
[ 2, 7, 9, 20],
[ 2, 7, 9, 20],
[ 2, 7, 9, 20]]),
array([[1, 1, 1, 1],
[6, 6, 6, 6],
[7, 7, 7, 7],
[9, 9, 9, 9]]))
这些数组是通过重复提供的值创建的。一个包含相同行中的值,另一个包含相同列中的其他值。行数和列数由另一个序列中的元素数决定。
因此,meshgrid
创建的两个数组在形状上与矢量运算兼容。想象一下页面顶部代码中的 x 和 y 序列具有不同数量的元素,X 和 Y 结果数组无论如何都将形状兼容,不需要任何 broadcast.
来源
numpy.meshgrid
来 from MATLAB, like many other NumPy functions. So you can also study the examples from MATLAB to see meshgrid
in use, the code for the 3D plotting looks the same in MATLAB.
大多数时候你只需要list(zip(X,Y))
其中 X = np.linspace(x)
和 Y = np.linspace(y)
谁能给我解释一下 Numpy 中 meshgrid
函数的用途是什么?我知道它会创建某种用于绘图的坐标网格,但我看不到它的直接好处。
我正在向 Sebastian Raschka 学习 "Python Machine Learning",他正在使用它来绘制决策边界。请参见输入 11 here.
我也试过官方文档中的这段代码,但同样,输出对我来说并没有真正意义。
x = np.arange(-5, 5, 1)
y = np.arange(-5, 5, 1)
xx, yy = np.meshgrid(x, y, sparse=True)
z = np.sin(xx**2 + yy**2) / (xx**2 + yy**2)
h = plt.contourf(x,y,z)
如果可能的话,请给我看很多真实世界的例子。
假设你有一个函数:
def sinus2d(x, y):
return np.sin(x) + np.sin(y)
并且您想要,例如,查看它在 0 到 2*pi 范围内的样子。你会怎么做? np.meshgrid
进来了:
xx, yy = np.meshgrid(np.linspace(0,2*np.pi,100), np.linspace(0,2*np.pi,100))
z = sinus2d(xx, yy) # Create the image on this grid
这样的情节看起来像:
import matplotlib.pyplot as plt
plt.imshow(z, origin='lower', interpolation='none')
plt.show()
所以np.meshgrid
只是方便而已。原则上同样可以通过以下方式完成:
z2 = sinus2d(np.linspace(0,2*np.pi,100)[:,None], np.linspace(0,2*np.pi,100)[None,:])
但是你需要知道你的尺寸(假设你有两个以上......)和正确的广播。 np.meshgrid
为您完成这一切。
此外,meshgrid 还允许您删除坐标和数据,例如,如果您想要进行插值但排除某些值:
condition = z>0.6
z_new = z[condition] # This will make your array 1D
那么你现在如何进行插值?您可以将 x
和 y
提供给像 scipy.interpolate.interp2d
这样的插值函数,因此您需要一种方法来知道删除了哪些坐标:
x_new = xx[condition]
y_new = yy[condition]
然后您仍然可以使用 "right" 坐标进行插值(尝试不使用 meshgrid,您将有很多额外的代码):
from scipy.interpolate import interp2d
interpolated = interp2d(x_new, y_new, z_new)
并且原始网格允许您再次在原始网格上进行插值:
interpolated_grid = interpolated(xx[0], yy[:, 0]).reshape(xx.shape)
这些只是我使用 meshgrid
的一些示例,可能还有更多。
meshgrid
的目的是用 x 值数组和 y 值数组创建矩形网格。
因此,例如,如果我们想要创建一个网格,在 x 和 y 方向上,我们在 0 到 4 之间的每个整数值处都有一个点。要创建矩形网格,我们需要 x
和 y
点的每个组合。
这将是 25 分,对吧?因此,如果我们想为所有这些点创建一个 x 和 y 数组,我们 可以 执行以下操作。
x[0,0] = 0 y[0,0] = 0
x[0,1] = 1 y[0,1] = 0
x[0,2] = 2 y[0,2] = 0
x[0,3] = 3 y[0,3] = 0
x[0,4] = 4 y[0,4] = 0
x[1,0] = 0 y[1,0] = 1
x[1,1] = 1 y[1,1] = 1
...
x[4,3] = 3 y[4,3] = 4
x[4,4] = 4 y[4,4] = 4
这将导致以下 x
和 y
矩阵,这样每个矩阵中对应元素的配对给出网格中某个点的 x 和 y 坐标。
x = 0 1 2 3 4 y = 0 0 0 0 0
0 1 2 3 4 1 1 1 1 1
0 1 2 3 4 2 2 2 2 2
0 1 2 3 4 3 3 3 3 3
0 1 2 3 4 4 4 4 4 4
然后我们可以绘制这些以验证它们是一个网格:
plt.plot(x,y, marker='.', color='k', linestyle='none')
显然,这变得非常乏味,尤其是对于大范围的 x
和 y
。相反,meshgrid
实际上可以为我们生成这个:我们必须指定的是唯一的 x
和 y
值。
xvalues = np.array([0, 1, 2, 3, 4]);
yvalues = np.array([0, 1, 2, 3, 4]);
现在,当我们调用 meshgrid
时,我们会自动获得之前的输出。
xx, yy = np.meshgrid(xvalues, yvalues)
plt.plot(xx, yy, marker='.', color='k', linestyle='none')
创建这些矩形网格对许多任务很有用。在您在 post 中提供的示例中,它只是一种在 x
和 y
的值范围内对函数 (sin(x**2 + y**2) / (x**2 + y**2)
) 进行采样的方法。
因为此函数已在矩形网格上采样,所以现在可以将此函数可视化为 "image"。
此外,现在可以将结果传递给需要矩形网格数据的函数(即 contourf
)
由微软提供 Excel:
其实np.meshgrid
的目的在文档中已经提到了:
Return coordinate matrices from coordinate vectors.
Make N-D coordinate arrays for vectorized evaluations of N-D scalar/vector fields over N-D grids, given one-dimensional coordinate arrays x1, x2,..., xn.
所以它的主要目的是创建一个坐标矩阵。
您可能刚刚问过自己:
为什么我们需要创建坐标矩阵?
你需要坐标矩阵 Python/NumPy 的原因是坐标与值之间没有直接关系,除非你的坐标从零开始并且是纯正整数。然后你可以只使用数组的索引作为索引。 但是,如果不是这种情况,您需要以某种方式将坐标与数据一起存储。这就是网格的用武之地。
假设你的数据是:
1 2 1
2 5 2
1 2 1
但是,每个值代表一个 3 x 2 公里的区域(水平 x 垂直)。假设你的原点是左上角,你想要代表你可以使用的距离的数组:
import numpy as np
h, v = np.meshgrid(np.arange(3)*3, np.arange(3)*2)
其中 v 是:
array([[0, 0, 0],
[2, 2, 2],
[4, 4, 4]])
和h:
array([[0, 3, 6],
[0, 3, 6],
[0, 3, 6]])
因此,如果您有两个索引,假设 x
和 y
(这就是为什么 meshgrid
的 return 值通常是 xx
或 xs
而不是 x
在这种情况下我选择 h
水平!)然后你可以得到点的 x 坐标,点的 y 坐标和那个点的值通过使用:
h[x, y] # horizontal coordinate
v[x, y] # vertical coordinate
data[x, y] # value
这使得跟踪坐标变得更加容易并且(更重要的是)您可以将它们传递给需要知道坐标的函数。
稍微长一点的解释
然而,np.meshgrid
本身并不经常直接使用,大多数人只是使用 similar 对象之一 np.mgrid
或 np.ogrid
。
这里 np.mgrid
代表 sparse=False
而 np.ogrid
代表 sparse=True
的情况(我指的是 np.meshgrid
的 sparse
论点)。请注意,两者之间存在显着差异
np.meshgrid
and np.ogrid
and np.mgrid
:前两个 returned 值(如果有两个或更多)被反转。通常这无关紧要,但您应该根据上下文给出有意义的变量名称。
例如,在二维网格和 matplotlib.pyplot.imshow
的情况下,将 return 的第一个 return 项目命名为 np.meshgrid
x
和第二个 y
而它是
np.mgrid
和 np.ogrid
.
np.ogrid
和稀疏网格
>>> import numpy as np
>>> yy, xx = np.ogrid[-5:6, -5:6]
>>> xx
array([[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]])
>>> yy
array([[-5],
[-4],
[-3],
[-2],
[-1],
[ 0],
[ 1],
[ 2],
[ 3],
[ 4],
[ 5]])
如前所述,与 np.meshgrid
相比,输出是相反的,这就是为什么我将其解压缩为 yy, xx
而不是 xx, yy
:
>>> xx, yy = np.meshgrid(np.arange(-5, 6), np.arange(-5, 6), sparse=True)
>>> xx
array([[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]])
>>> yy
array([[-5],
[-4],
[-3],
[-2],
[-1],
[ 0],
[ 1],
[ 2],
[ 3],
[ 4],
[ 5]])
这看起来像坐标,特别是二维绘图的 x 和 y 线。
可视化:
yy, xx = np.ogrid[-5:6, -5:6]
plt.figure()
plt.title('ogrid (sparse meshgrid)')
plt.grid()
plt.xticks(xx.ravel())
plt.yticks(yy.ravel())
plt.scatter(xx, np.zeros_like(xx), color="blue", marker="*")
plt.scatter(np.zeros_like(yy), yy, color="red", marker="x")
np.mgrid
和dense/fleshed出格
>>> yy, xx = np.mgrid[-5:6, -5:6]
>>> xx
array([[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]])
>>> yy
array([[-5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5],
[-4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4],
[-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3],
[-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2],
[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
[ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4],
[ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]])
这里同样适用:输出与np.meshgrid
相反:
>>> xx, yy = np.meshgrid(np.arange(-5, 6), np.arange(-5, 6))
>>> xx
array([[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]])
>>> yy
array([[-5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5],
[-4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4],
[-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3],
[-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2],
[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
[ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4],
[ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]])
与ogrid
不同,这些数组包含所有 xx
和yy
坐标在-5 <= xx <= 5; -5 <= yy <= 5 格。
yy, xx = np.mgrid[-5:6, -5:6]
plt.figure()
plt.title('mgrid (dense meshgrid)')
plt.grid()
plt.xticks(xx[0])
plt.yticks(yy[:, 0])
plt.scatter(xx, yy, color="red", marker="x")
功能
它不仅限于 2D,这些函数适用于任意维度(好吧,在 Python 中为函数提供了最大数量的参数以及 NumPy 允许的最大维度数量):
>>> x1, x2, x3, x4 = np.ogrid[:3, 1:4, 2:5, 3:6]
>>> for i, x in enumerate([x1, x2, x3, x4]):
... print('x{}'.format(i+1))
... print(repr(x))
x1
array([[[[0]]],
[[[1]]],
[[[2]]]])
x2
array([[[[1]],
[[2]],
[[3]]]])
x3
array([[[[2],
[3],
[4]]]])
x4
array([[[[3, 4, 5]]]])
>>> # equivalent meshgrid output, note how the first two arguments are reversed and the unpacking
>>> x2, x1, x3, x4 = np.meshgrid(np.arange(1,4), np.arange(3), np.arange(2, 5), np.arange(3, 6), sparse=True)
>>> for i, x in enumerate([x1, x2, x3, x4]):
... print('x{}'.format(i+1))
... print(repr(x))
# Identical output so it's omitted here.
即使这些也适用于一维,但有两个(更常见的)一维网格创建函数:
除了start
和stop
参数外,它还支持step
参数(即使是表示步骤数的复杂步骤):
>>> x1, x2 = np.mgrid[1:10:2, 1:10:4j]
>>> x1 # The dimension with the explicit step width of 2
array([[1., 1., 1., 1.],
[3., 3., 3., 3.],
[5., 5., 5., 5.],
[7., 7., 7., 7.],
[9., 9., 9., 9.]])
>>> x2 # The dimension with the "number of steps"
array([[ 1., 4., 7., 10.],
[ 1., 4., 7., 10.],
[ 1., 4., 7., 10.],
[ 1., 4., 7., 10.],
[ 1., 4., 7., 10.]])
应用程序
您特意询问了用途,事实上,如果您需要坐标系,这些网格非常有用。
例如,如果您有一个计算二维距离的 NumPy 函数:
def distance_2d(x_point, y_point, x, y):
return np.hypot(x-x_point, y-y_point)
而您想知道每个点的距离:
>>> ys, xs = np.ogrid[-5:5, -5:5]
>>> distances = distance_2d(1, 2, xs, ys) # distance to point (1, 2)
>>> distances
array([[9.21954446, 8.60232527, 8.06225775, 7.61577311, 7.28010989,
7.07106781, 7. , 7.07106781, 7.28010989, 7.61577311],
[8.48528137, 7.81024968, 7.21110255, 6.70820393, 6.32455532,
6.08276253, 6. , 6.08276253, 6.32455532, 6.70820393],
[7.81024968, 7.07106781, 6.40312424, 5.83095189, 5.38516481,
5.09901951, 5. , 5.09901951, 5.38516481, 5.83095189],
[7.21110255, 6.40312424, 5.65685425, 5. , 4.47213595,
4.12310563, 4. , 4.12310563, 4.47213595, 5. ],
[6.70820393, 5.83095189, 5. , 4.24264069, 3.60555128,
3.16227766, 3. , 3.16227766, 3.60555128, 4.24264069],
[6.32455532, 5.38516481, 4.47213595, 3.60555128, 2.82842712,
2.23606798, 2. , 2.23606798, 2.82842712, 3.60555128],
[6.08276253, 5.09901951, 4.12310563, 3.16227766, 2.23606798,
1.41421356, 1. , 1.41421356, 2.23606798, 3.16227766],
[6. , 5. , 4. , 3. , 2. ,
1. , 0. , 1. , 2. , 3. ],
[6.08276253, 5.09901951, 4.12310563, 3.16227766, 2.23606798,
1.41421356, 1. , 1.41421356, 2.23606798, 3.16227766],
[6.32455532, 5.38516481, 4.47213595, 3.60555128, 2.82842712,
2.23606798, 2. , 2.23606798, 2.82842712, 3.60555128]])
如果通过密集网格而不是开放网格,输出将是相同的。 NumPys 广播使之成为可能!
让我们想象一下结果:
plt.figure()
plt.title('distance to point (1, 2)')
plt.imshow(distances, origin='lower', interpolation="none")
plt.xticks(np.arange(xs.shape[1]), xs.ravel()) # need to set the ticks manually
plt.yticks(np.arange(ys.shape[0]), ys.ravel())
plt.colorbar()
这也是 NumPys mgrid
和 ogrid
变得非常方便的时候,因为它允许您轻松更改网格的分辨率:
ys, xs = np.ogrid[-5:5:200j, -5:5:200j]
# otherwise same code as above
但是,由于 imshow
不支持 x
和 y
输入,因此必须手动更改刻度。如果它接受 x
和 y
坐标,那将非常方便,对吗?
用 NumPy 编写自然处理网格的函数很容易。此外,NumPy,SciPy,matplotlib 中有几个函数希望您在网格中传递。
我喜欢图片所以让我们探索一下 matplotlib.pyplot.contour
:
ys, xs = np.mgrid[-5:5:200j, -5:5:200j]
density = np.sin(ys)-np.cos(xs)
plt.figure()
plt.contour(xs, ys, density)
注意坐标是如何正确设置的!如果您只是传入 density
.
或者使用 astropy models 给出另一个有趣的例子(这次我不太关心坐标,我只是用它们来创建 一些 网格):
from astropy.modeling import models
z = np.zeros((100, 100))
y, x = np.mgrid[0:100, 0:100]
for _ in range(10):
g2d = models.Gaussian2D(amplitude=100,
x_mean=np.random.randint(0, 100),
y_mean=np.random.randint(0, 100),
x_stddev=3,
y_stddev=3)
z += g2d(x, y)
a2d = models.AiryDisk2D(amplitude=70,
x_0=np.random.randint(0, 100),
y_0=np.random.randint(0, 100),
radius=5)
z += a2d(x, y)
虽然那只是“为了外表”与功能模型和拟合相关的所有功能(例如scipy.interpolate.interp2d
,
scipy.interpolate.griddata
甚至在 Scipy 中使用 np.mgrid
) 显示示例,等等需要网格。其中大部分适用于开放网格和密集网格,但有些仅适用于其中之一。
meshgrid 有助于从两个一维数组创建一个矩形网格,该数组包含两个数组中的所有点对。
x = np.array([0, 1, 2, 3, 4])
y = np.array([0, 1, 2, 3, 4])
现在,如果您已经定义了一个函数 f(x,y) 并且您想要将此函数应用于数组 'x' 和 'y' 中所有可能的点组合,那么您可以这样做:
f(*np.meshgrid(x, y))
比如说,如果您的函数只生成两个元素的乘积,那么这就是笛卡尔乘积的实现方式,对大型数组非常有效。
引用自here
基本思路
给定可能的 x 值,xs
,(将它们视为绘图 x 轴上的刻度线)和可能的 y 值,ys
,meshgrid
生成相应的一组 (x, y) 网格点---类似于 set((x, y) for x in xs for y in yx)
。例如,如果 xs=[1,2,3]
和 ys=[4,5,6]
,我们将得到坐标集 {(1,4), (2,4), (3,4), (1,5), (2,5), (3,5), (1,6), (2,6), (3,6)}
.
Return 值的形式
但是meshgrid
returns的表示与上面的表达有两点不同:
首先,meshgrid
在二维数组中布置网格点:行对应不同的y值,列对应不同的x值---如在 list(list((x, y) for x in xs) for y in ys)
中,将给出以下数组:
[[(1,4), (2,4), (3,4)],
[(1,5), (2,5), (3,5)],
[(1,6), (2,6), (3,6)]]
第二个,meshgrid
returns x 和 y 坐标分别(即在两个不同的 numpy 二维数组中):
xcoords, ycoords = (
array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3]]),
array([[4, 4, 4],
[5, 5, 5],
[6, 6, 6]]))
# same thing using np.meshgrid:
xcoords, ycoords = np.meshgrid([1,2,3], [4,5,6])
# same thing without meshgrid:
xcoords = np.array([xs] * len(ys)
ycoords = np.array([ys] * len(xs)).T
注意,np.meshgrid
也可以生成更高维度的网格。给定 xs、ys 和 zs,您将返回 xcoords、ycoords、zcoords 作为 3d 数组。 meshgrid
还支持维度的反向排序以及结果的稀疏表示。
应用程序
为什么我们需要这种形式的输出?
在网格上的每个点应用函数:
一个动机是像 (+, -, *, /, **) 这样的二元运算符作为元素操作对 numpy 数组进行了重载。这意味着如果我有一个函数 def f(x, y): return (x - y) ** 2
适用于两个标量,我也可以将它应用于两个 numpy 数组以获得元素结果数组:例如f(xcoords, ycoords)
或 f(*np.meshgrid(xs, ys))
在上面的示例中给出以下内容:
array([[ 9, 4, 1],
[16, 9, 4],
[25, 16, 9]])
高维外积:我不确定这样的效率如何,但是你可以这样得到高维外积:np.prod(np.meshgrid([1,2,3], [1,2], [1,2,3,4]), axis=0)
.
matplotlib 中的等高线图: 我在调查 drawing contour plots with matplotlib for plotting decision boundaries 时遇到 meshgrid
。为此,您使用 meshgrid
生成一个网格,在每个网格点评估函数(例如,如上所示),然后将 xcoords、ycoords 和计算的 f 值(即 zcoords)传递给 contourf 函数。
简答
meshgrid
的目的是通过 C NumPy 库中的矢量化操作来帮助 replace Python loops(缓慢的解释代码)。
借自 this site.
x = np.arange(-4, 4, 0.25)
y = np.arange(-4, 4, 0.25)
X, Y = np.meshgrid(x, y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
meshgrid
用于创建 -4 和 +4 之间的坐标对,在 X 和 Y 的每个方向上增量为 0.25。然后使用每一对从中找到 R 和 Z。这种准备坐标“网格”的方法经常用于绘制 3D 表面或为 2D 表面着色。
详情:Python for-loop vs NumPy 向量运算
举一个更简单的例子,假设我们有两个值序列,
a = [2,7,9,20]
b = [1,6,7,9]
我们想对每对可能的值执行操作,一个取自第一个列表,一个取自第二个列表。我们还想存储结果。例如,假设我们想要获得每个可能对的值的总和。
缓慢费力的方法
c = []
for i in range(len(b)):
row = []
for j in range(len(a)):
row.append (a[j] + b[i])
c.append (row)
print (c)
结果:
[[3, 8, 10, 21],
[8, 13, 15, 26],
[9, 14, 16, 27],
[11, 16, 18, 29]]
Python是解释的,这些循环执行起来比较慢。
快速简便的方法
meshgrid
旨在从代码中删除循环。它 returns 两个数组(下面的 i 和 j)可以组合起来扫描所有现有的对:
i,j = np.meshgrid (a,b)
c = i + j
print (c)
结果:
[[ 3 8 10 21]
[ 8 13 15 26]
[ 9 14 16 27]
[11 16 18 29]]
引擎盖下的 Meshgrid
meshgrid
准备的两个数组是:
(array([[ 2, 7, 9, 20],
[ 2, 7, 9, 20],
[ 2, 7, 9, 20],
[ 2, 7, 9, 20]]),
array([[1, 1, 1, 1],
[6, 6, 6, 6],
[7, 7, 7, 7],
[9, 9, 9, 9]]))
这些数组是通过重复提供的值创建的。一个包含相同行中的值,另一个包含相同列中的其他值。行数和列数由另一个序列中的元素数决定。
因此,meshgrid
创建的两个数组在形状上与矢量运算兼容。想象一下页面顶部代码中的 x 和 y 序列具有不同数量的元素,X 和 Y 结果数组无论如何都将形状兼容,不需要任何 broadcast.
来源
numpy.meshgrid
来 from MATLAB, like many other NumPy functions. So you can also study the examples from MATLAB to see meshgrid
in use, the code for the 3D plotting looks the same in MATLAB.
大多数时候你只需要list(zip(X,Y))
其中 X = np.linspace(x)
和 Y = np.linspace(y)