Подтвердить что ты не робот

Ненужный мешгрид в 3D

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

4b9b3361

Ответ 1

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

Ответ 2

Numpy (начиная с 1.8, я думаю) теперь поддерживает более высокую, чем 2D генерация позиционных сеток с meshgrid. Одним из важных дополнений, которые мне действительно помогли, является возможность выбрать порядок индексирования (либо 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_)

Ответ 3

Можете ли вы показать нам, как вы используете 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 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 для .

Ответ 4

Я думаю, что вы хотите

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

например.

Ответ 5

Вместо того, чтобы писать новую функцию, 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))'

Ответ 6

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

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

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