2009-12-01 67 views
36

Numpy的meshgrid對於將兩個向量轉換爲座標網格非常有用。將此擴展到三維的最簡單方法是什麼?因此,給定三個向量x,y和z,構造可用作座標的3x3D數組(而不是2x2D數組)。3D中的Numpy meshgrid

回答

26

這裏是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) 
+1

在3D網格的情況下,使用類似於在numpy doc中爲meshgrib提供的樣本,這將返回Z,Y,X而不是X,Y,Z。 用'return tuple(ans [:: - 1])替換return語句可以解決這個問題。 – levesque 2011-02-10 15:51:22

+0

@Paul如果x或y數組的長度很長,則x.repeat()命令崩潰併發送Memory Error。有什麼辦法可以避免這個錯誤? – Dalek 2014-02-03 23:41:35

+0

@Dalek數組有多長?難道你的內存不足?例如,如果有3個數組,每個條目有4096個條目,並且每個條目都保存雙倍(即8個字節),那麼對於單獨的條目,我們需要(8 * 4 * 2 ** 10)** 3個字節= 2 ** 45個字節= 32 * 2 ** 40個字節= 32TB的內存,這顯然很有用。我希望我在這裏沒有犯錯。 – 2014-02-24 19:25:11

5

我想你想要的是

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

例如。

+0

謝謝,但這是不太什麼我需要 - meshgrid實際上使用向量的值來生成2D數組,並且這些值可以不規則地間隔開。 – astrofrog 2009-12-01 18:56:47

7

你能告訴我們你是如何使用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即可實現廣播。

請參閱http://www.scipy.org/EricsBroadcastingDoc關於numpy廣播的更多信息。

4

而是寫一個新的功能,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

如果你能說出來怎麼樣會很好...... – 2013-08-13 07:57:08

4

這裏是meshgrid的多維版本,我寫:

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

注意,返回的數組是示原始陣列數據,所以改變原始數組會影響座標數組。

+0

爲我做了竅門,非常感謝! – somada141 2013-08-15 07:51:55

31

Numpy(截至1.8我認爲)現在支持更高的2D代位置網格與meshgrid。其中一個重要的除了這真的幫了我是(分別要麼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_)