2009-12-01 54 views
36

Numpyのmeshgridは、2つのベクトルを座標グリッドに変換するのに非常に便利です。これを3次元に拡張する最も簡単な方法は何ですか? 3つのベクトルx、y、zが与えられた場合、(2x2D配列の代わりに)座標として使用できる3x3D配列を作成します。Numpy meshgrid in 3D

答えて

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

meshgribのnumpy docのようなサンプルを使って3dメッシュグリッドの場合、これはX、Y、ZではなくZ、Y、Xを返します。 return文を 'return tuple(ans [:: - 1]) 'に置き換えるとこれを修正できます。 – levesque

+0

@Paul xまたはy配列の長さが長い場合、x.repeat()コマンドはクラッシュしてメモリエラーを送信します。このエラーを回避する方法はありますか? – Dalek

+0

@Dalek配列の長さはどのくらいですか?あなたは記憶がなくなってしまうことがありますか?例えば、配列が3つあり、それぞれ4096個のエントリがあり、各エントリがダブル(つまり8バイト)を保持している場合、エントリだけのために(8 * 4 * 2 ** 10)** 3バイト= 2 ** 45バイト= 32 * 2 ** 40バイト= 32 TBのメモリ。これは明らかに楽しいことです。私はここでミスをしていないことを願っています。 –

5

私は何をしたいことは例えば

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

だと思います。

+0

おかげで、これはかなりのものではありませんmeshgridは実際にはベクトルの値を使って2D配列を生成し、値は不規則に配置されています。 – astrofrog

7

np.meshgridの使い方を教えていただけますか? numpyブロードキャストは繰り返し配列を生成せずに同じことをすることができるので、あなたが本当にmeshgridを必要としないことは非常に良いチャンスです。例えば

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を参照してください。ここで

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

どうすればいいか分かりますか?... –

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

31

Numpy(1.8の考え方で)は、meshgridで位置グリッドの2D生成をサポートするようになりました。本当に私を助けた一つの重要な追加は、私は、次の例で検証インデックスの順序を選択した能力(xyまたはデカルトや行列のインデックスのためのijのいずれかにそれぞれ)、次のとおりです。

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_) 
関連する問題