web-dev-qa-db-ja.com

3DのNumpy Meshgrid

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

41
astrofrog

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

Numpy(1.8の時点で)は、 meshgrid を使用して、位置グリッドの2Dよりも高い生成をサポートするようになりました。本当に役立った重要な追加の1つは、インデックスの順序を選択できることです(それぞれ、デカルトまたはマトリックスインデックスの場合は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_)
43
leifdenby

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

7
unutbu

あなたが望むのは

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

例えば。

5
Autoplectic

以下は、私が書いたmeshgridの多次元バージョンです。

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

返される配列は元の配列データのビューであるため、元の配列を変更すると座標配列に影響することに注意してください。

4
user545424

新しい関数を作成する代わりに、 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
j13r