【问题标题】:Numpy meshgrid in 3D3D 中的 Numpy 网格
【发布时间】:2010-12-22 02:23:22
【问题描述】:

Numpy 的 meshgrid 对于将两个向量转换为坐标网格非常有用。将其扩展到三个维度的最简单方法是什么?所以给定三个向量 x、y 和 z,构造 3x3D 数组(而不是 2x2D 数组)作为坐标。

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    您可以通过更改顺序来实现:

    import numpy as np
    xx = np.array([1,2,3,4])
    yy = np.array([5,6,7])
    zz = np.array([9,10])
    y, z, x = np.meshgrid(yy, zz, xx)
    

    【讨论】:

      【解决方案2】:

      Numpy(我认为从 1.8 开始)现在支持使用meshgrid 生成高于 2D 的位置网格。一个真正帮助我的重要补充是能够选择索引顺序(xyij 分别用于笛卡尔或矩阵索引),我通过以下示例进行了验证:

      import numpy as np
      
      x_ = np.linspace(0., 1., 10)
      y_ = np.linspace(1., 2., 20)
      z_ = np.linspace(3., 4., 30)
      
      x, y, z = np.meshgrid(x_, y_, z_, indexing='ij')
      
      assert np.all(x[:,0,0] == x_)
      assert np.all(y[0,:,0] == y_)
      assert np.all(z[0,0,:] == z_)
      

      【讨论】:

      • 断言有什么作用?为什么有必要在那里?
      • assert 只是检查沿 x、y 和 z 轴的索引是否等于预期的 *_ 变量。不需要。
      • 这应该是公认的答案,以避免人们重新发明轮子。
      【解决方案3】:

      numpy.ix_ 应该做你想做的,而不是写一个新函数。

      这是文档中的一个示例:

      >>> ixgrid = np.ix_([0,1], [2,4])
      >>> ixgrid
      (array([[0],
         [1]]), array([[2, 4]]))
      >>> ixgrid[0].shape, ixgrid[1].shape
      ((2, 1), (1, 2))'
      

      【讨论】:

        【解决方案4】:

        这是我编写的多维网格网格:

        def ndmesh(*args):
           args = map(np.asarray,args)
           return np.broadcast_arrays(*[x[(slice(None),)+(None,)*i] for i, x in enumerate(args)])
        

        注意返回的数组是原始数组数据的视图,所以改变原始数组会影响坐标数组。

        【讨论】:

          【解决方案5】:

          这里是meshgrid的源码:

          def meshgrid(x,y):
              """
              Return coordinate matrices from two coordinate vectors.
          
              Parameters
              ----------
              x, y : ndarray
                  Two 1-D arrays representing the x and y coordinates of a grid.
          
              Returns
              -------
              X, Y : ndarray
                  For vectors `x`, `y` with lengths ``Nx=len(x)`` and ``Ny=len(y)``,
                  return `X`, `Y` where `X` and `Y` are ``(Ny, Nx)`` shaped arrays
                  with the elements of `x` and y repeated to fill the matrix along
                  the first dimension for `x`, the second for `y`.
          
              See Also
              --------
              index_tricks.mgrid : Construct a multi-dimensional "meshgrid"
                                   using indexing notation.
              index_tricks.ogrid : Construct an open multi-dimensional "meshgrid"
                                   using indexing notation.
          
              Examples
              --------
              >>> X, Y = np.meshgrid([1,2,3], [4,5,6,7])
              >>> X
              array([[1, 2, 3],
                     [1, 2, 3],
                     [1, 2, 3],
                     [1, 2, 3]])
              >>> Y
              array([[4, 4, 4],
                     [5, 5, 5],
                     [6, 6, 6],
                     [7, 7, 7]])
          
              `meshgrid` is very useful to evaluate functions on a grid.
          
              >>> x = np.arange(-5, 5, 0.1)
              >>> y = np.arange(-5, 5, 0.1)
              >>> xx, yy = np.meshgrid(x, y)
              >>> z = np.sin(xx**2+yy**2)/(xx**2+yy**2)
          
              """
              x = asarray(x)
              y = asarray(y)
              numRows, numCols = len(y), len(x)  # yes, reversed
              x = x.reshape(1,numCols)
              X = x.repeat(numRows, axis=0)
          
              y = y.reshape(numRows,1)
              Y = y.repeat(numCols, axis=1)
              return X, Y
          

          这很容易理解。我将模式扩展到任意数量的维度,但这段代码绝不是优化的(也没有彻底检查错误),但你得到了你所付出的。希望对您有所帮助:

          def meshgrid2(*arrs):
              arrs = tuple(reversed(arrs))  #edit
              lens = map(len, arrs)
              dim = len(arrs)
          
              sz = 1
              for s in lens:
                  sz*=s
          
              ans = []    
              for i, arr in enumerate(arrs):
                  slc = [1]*dim
                  slc[i] = lens[i]
                  arr2 = asarray(arr).reshape(slc)
                  for j, sz in enumerate(lens):
                      if j!=i:
                          arr2 = arr2.repeat(sz, axis=j) 
                  ans.append(arr2)
          
              return tuple(ans)
          

          【讨论】:

          • 在 3d 网格的情况下,使用类似于 numpy doc 中为 meshgrib 提供的样本,这将返回 Z、Y、X 而不是 X、Y、Z。用return tuple(ans[::-1]) 替换return 语句可以解决这个问题。
          • @Paul 如果 x 或 y 数组的长度很长,则 x.repeat() 命令崩溃并发送内存错误。有什么办法可以避免这个错误?
          • @Dalek 阵列有多长?会不会是你内存不够了?例如,如果有 3 个数组,每个数组有 4096 个条目,并且每个条目包含一个双精度(即 8 字节),那么仅对于条目我们需要 (8 * 4 * 210)**3 bytes = 245 字节 = 32 * 2**40 字节 = 32 TB 内存,这显然是巨大的。我希望我没有在这里犯错。
          【解决方案6】:

          你能告诉我们你是如何使用 np.meshgrid 的吗?很有可能你真的不需要 meshgrid,因为 numpy 广播可以做同样的事情而不会生成重复的数组。

          例如,

          import numpy as np
          
          x=np.arange(2)
          y=np.arange(3)
          [X,Y] = np.meshgrid(x,y)
          S=X+Y
          
          print(S.shape)
          # (3, 2)
          # Note that meshgrid associates y with the 0-axis, and x with the 1-axis.
          
          print(S)
          # [[0 1]
          #  [1 2]
          #  [2 3]]
          
          s=np.empty((3,2))
          print(s.shape)
          # (3, 2)
          
          # x.shape is (2,).
          # y.shape is (3,).
          # x's shape is broadcasted to (3,2)
          # y varies along the 0-axis, so to get its shape broadcasted, we first upgrade it to
          # have shape (3,1), using np.newaxis. Arrays of shape (3,1) can be broadcasted to
          # arrays of shape (3,2).
          s=x+y[:,np.newaxis]
          print(s)
          # [[0 1]
          #  [1 2]
          #  [2 3]]
          

          关键是S=X+Y可以而且应该被s=x+y[:,np.newaxis]替换,因为 后者不需要形成(可能很大的)重复阵列。它还可以轻松推广到更高维度(更多轴)。您只需在需要的地方添加np.newaxis 即可根据需要进行广播。

          有关 numpy 广播的更多信息,请参阅http://www.scipy.org/EricsBroadcastingDoc

          【讨论】:

            【解决方案7】:

            我认为你想要的是

            X, Y, Z = numpy.mgrid[-10:10:100j, -10:10:100j, -10:10:100j]
            

            例如。

            【讨论】:

            • 谢谢,但这并不是我所需要的——meshgrid 实际上使用向量的值来生成二维数组,并且这些值可以不规则地间隔。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-09-28
            • 1970-01-01
            • 2021-12-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多