谁能给我解释一下Numpy中网格函数的目的是什么?我知道它创建了某种用于绘图的坐标网格,但我真的看不到它的直接好处。

我正在学习Sebastian Raschka的“Python机器学习”,他正在用它来绘制决策边界。请看这里的输入11。

我也从官方文档中尝试了这段代码,但是,同样,输出对我来说没有意义。

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)

如果可能的话,请给我展示一些真实的例子。


当前回答

幕后故事:

import numpy as np

def meshgrid(x , y):
    XX = []
    YY = []
    for colm in range(len(y)):
        XX.append([])
        YY.append([])
        for row in range(len(x)):
            XX[colm].append(x[row])
            YY[colm].append(y[colm])
    return np.asarray(XX), np.asarray(YY)

让我们以@Sarsaparilla的答案为例:

y = [7, 6, 5]
x = [1, 2, 3, 4]

xx, yy = meshgrid(x , y)

输出:

>>> xx
array([[1, 2, 3, 4],
       [1, 2, 3, 4],
       [1, 2, 3, 4]])

>>> yy
array([[7, 7, 7, 7],
       [6, 6, 6, 6],
       [5, 5, 5, 5]])

其他回答

假设你有一个函数:

def sinus2d(x, y):
    return np.sin(x) + np.sin(y)

比如说,你想看看它在0到2*范围内是什么样子。你会怎么做?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。网格只是一种方便。原则上,同样可以通过以下方法做到:

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. interpolation .interp2d,所以你需要一种方法来知道哪些坐标被删除了:

x_new = xx[condition]
y_new = yy[condition]

然后你仍然可以插入“正确的”坐标(尝试没有网格,你会有很多额外的代码):

from scipy.interpolate import interp2d
interpolated = interp2d(x_new, y_new, z_new)

原始网格允许你再次得到原始网格上的插值:

interpolated_grid = interpolated(xx[0], yy[:, 0]).reshape(xx.shape)

这些只是我使用网格的一些例子,可能还有更多。

简短的回答

meshgrid的目的是通过NumPy库中更快的向量化操作来帮助取代缓慢的Python循环。meshgrid角色是准备向量化操作所需的2D数组。

基本的例子说明了原理

假设我们有两个值序列,

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]]

快速简便的方法

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]]

从这个基本示例中,您可以看到Numpy库中显式的慢Python循环是如何被隐藏的更快的C循环所取代的。这个原理被广泛应用于3D操作,包括彩色像素地图。常见的例子是3D图。

常用:3D绘图

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的每个方向上增加.25,然后使用每对坐标对从中找到R和Z。这种准备坐标“网格”的方法经常用于绘制3D曲面,或为2D曲面着色。

引擎盖下的网格

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]]))

这些数组是通过水平或垂直重复所提供的值来创建的。对于矢量操作,这两个数组是形状兼容的。

起源

numpy。像许多其他NumPy函数一样,meshgrid来自MATLAB。所以你也可以研究MATLAB中的例子,看看网格在使用中,三维绘图的代码在MATLAB中看起来是一样的。

基本思想

给定可能的x值xs(可以把它们看作是图形x轴上的标记)和可能的y值ys, meshgrid生成相应的(x, y)网格点集——类似于set((x, y) for x in xs for y in yx)。例如,如果x =(1、2、3),y =(4、5、6),我们会得到一组坐标{(1,4)(2、4),(3、4),(1、5),(2、5),(3、5),(6),(2,6),(6)}。

返回值的形式

但是,meshgrid返回的表示与上面的表达式有两个不同之处:

首先,meshgrid在2d数组中布局网格点:行对应不同的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分别返回x和y坐标(即在两个不同的numpy 2d数组中):

   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,你会得到xcods ycods zcods作为3d数组。网格还支持维度的反向排序以及结果的稀疏表示。

应用程序

为什么我们需要这种形式的输出?

在网格的每个点上应用一个函数: 一个动机是二进制操作符(+,-,*,/,**)作为元素级操作符重载numpy数组。这意味着如果我有一个函数def f(x, y): return (x - y) ** 2,它在两个标量上工作,我也可以将它应用在两个numpy数组上,以获得一个elementwise结果的数组:例如f(xcoordinates, ycoords)或f(*np。Meshgrid (xs, ys))在上面的例子中给出了以下内容:

array([[ 9,  4,  1],
       [16,  9,  4],
       [25, 16,  9]])

高维外积:我不确定这有多有效,但你可以这样得到高维外积:np.prod(np. prod)Meshgrid([1,2,3],[1,2],[1,2,3,4]),轴=0)。

matplotlib中的等高线图:在研究用matplotlib绘制等高线图以绘制决策边界时,我遇到了网格。为此,你用meshgrid生成一个网格,计算每个网格点的函数(如上图所示),然后将xcods, ycods和计算的f值(即zcods)传递到contourf函数中。

微软Excel提供:

meshgrid有助于从两个1-D数组的所有点对中创建一个矩形网格。

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))

比如说,如果你的函数只产生两个元素的乘积,那么这就是笛卡尔积的实现方式,对于大型数组来说是有效的。

此处引用