Вопрос

Meshgrid от Numpy очень полезен для преобразования двух векторов в координатную сетку.Каков самый простой способ распространить это на три измерения?Итак, учитывая три вектора x, y и z, постройте массивы 3x3D (вместо массивов 2x2D), которые можно использовать в качестве координат.

Это было полезно?

Решение

Вот исходный код 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)

Другие советы

Numpy (по состоянию на 1.8, я думаю) теперь поддерживает более высокую, чем 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_)

Можете ли вы показать нам, как вы используете np.meshgrid?Существует очень большая вероятность, что вам действительно не нужна meshgrid, потому что numpy broadcasting может делать то же самое, не генерируя повторяющийся массив.

Например,

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 broadcasting читайте здесь.

я думаю, что то, чего ты хочешь, это

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

например.

Вот многомерная версия meshgrid , которую я написал:

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

Обратите внимание, что возвращаемые массивы являются представлениями исходных данных массива, поэтому изменение исходных массивов повлияет на массивы координат.

Вместо того, чтобы писать новую функцию, тупица.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))'
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top