numpy.meshgrid

numpy.meshgrid(x1, x2,..., xn, **kwargs)

Функция numpy.meshgrid() создает список массивов координатных сеток N-мерного координатного пространства для указанных одномерных массивов координатных векторов. Координатное пространство - это пространство N-мерных точек-координат, причем каждой точке в таком пространстве соответствует комбинация одного значения из каждого координатного массива.

Параметры:
x1, x2,..., xn - последовательность
Одномерные массивы, которые определяют координатную сетку.
indexing - ‘xy’, ‘ij’ (необязательный)
Определяет декартово ‘xy’ (по умолчанию) или матричное ‘ij’ индексирование выходного массива.
sparse - True или False (необязательный)
Если True, то для экономии памяти выводятся сжатые до одной оси массивы координатных сеток. По умолчанию sparse = False.
copy - True или False (необязательный)
Если False, то для экономии памяти возвращается представление исходных координатных массивов. По умолчанию copy = True.
Возвращает:
[X1, X2, X3, ... , Xn] - список массивов NumPy

Для N входных одномерных координатных векторов возвращается список массивов координатных cеток. Если длинна координатных массивов len(x1) = L1; len(x2) = L2; len(xN) = LN, то при indexing = 'ij' размеры массивов координатных сеток будут равны (L1, L2, L3, ... , LN). В случае, если параметр indexing = 'xy', то размеры массивов координатных сеток будут (L2, L1, L3, ... , LN), при этом повторение элементов так же окажется несколько инным.

В двумерном случае, когда длинна массива x1 равна M, а длинна вектора x2 равна N, то при indexing = 'xy' размеры массивов координатных сеток будут равны (N, M), а при indexing = 'ij' (M, N).

Допускаются случаи 0-мерного и 1-мерного пространства.

Смотрите так же: mgrid, ogrid

Замечание

Важно помнить, что если параметры sparse и copy равны False, то скорее всего будут возвращеные несмежные массивы. Кроме того, к одной ячейке памяти могут относиться несколько элементов транслируемого массива.

Примеры

>>> import numpy as np
>>> 
>>> x = [1, 2, 3, 4, 5]
>>> 
>>> y = [0, 5, 10, 15, 20, 25, 30]
>>> 
>>> #  Список координатных сеток:
... XY = np.meshgrid(x, y)
>>> XY
[array([[1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5]]),
array([[ 0,  0,  0,  0,  0],
       [ 5,  5,  5,  5,  5],
       [10, 10, 10, 10, 10],
       [15, 15, 15, 15, 15],
       [20, 20, 20, 20, 20],
       [25, 25, 25, 25, 25],
       [30, 30, 30, 30, 30]])]
>>>
>>> # Распаковка координатных сеток в отдельные массивы
... xy_grid, yx_grid = np.meshgrid(x, y)
>>> 
>>> xy_grid
array([[1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5]])
>>> 
>>> xy_grid.shape, len(x), len(y)
((7, 5), 5, 7)
>>> 
>>> yx_grid
array([[ 0,  0,  0,  0,  0],
       [ 5,  5,  5,  5,  5],
       [10, 10, 10, 10, 10],
       [15, 15, 15, 15, 15],
       [20, 20, 20, 20, 20],
       [25, 25, 25, 25, 25],
       [30, 30, 30, 30, 30]])
>>> 
>>> yx_grid.shape, len(x), len(y)
((7, 5), 5, 7)

Установка параметра indexing в значение 'ij', приводит к тому, что размеры массивов координатных сеток меняются, при этом несколько меняется и порядок повторения элементов:

>>> x = [1, 2]
>>> y = [0, 5, 10]
>>> z = [0, 0.1, 0.2, 0.3]
>>> 
>>> XYZ_indexingXY = np.meshgrid(x, y, z)
>>> XYZ_indexingXY
[array([[[1, 1, 1, 1],
         [2, 2, 2, 2]],

        [[1, 1, 1, 1],
         [2, 2, 2, 2]],

        [[1, 1, 1, 1],
         [2, 2, 2, 2]]]), 

array([[[ 0,  0,  0,  0],
        [ 0,  0,  0,  0]],

       [[ 5,  5,  5,  5],
        [ 5,  5,  5,  5]],

       [[10, 10, 10, 10],
        [10, 10, 10, 10]]]), 
        
array([[[ 0. ,  0.1,  0.2,  0.3],
        [ 0. ,  0.1,  0.2,  0.3]],

       [[ 0. ,  0.1,  0.2,  0.3],
        [ 0. ,  0.1,  0.2,  0.3]],

       [[ 0. ,  0.1,  0.2,  0.3],
        [ 0. ,  0.1,  0.2,  0.3]]])]
>>> 
>>>
>>> XYZ_indexingIJ = np.meshgrid(x, y, z, indexing = 'ij')
>>> XYZ_indexingIJ
[array([[[1, 1, 1, 1],
         [1, 1, 1, 1],
         [1, 1, 1, 1]],

        [[2, 2, 2, 2],
         [2, 2, 2, 2],
         [2, 2, 2, 2]]]), 
        
array([[[ 0,  0,  0,  0],
        [ 5,  5,  5,  5],
        [10, 10, 10, 10]],

       [[ 0,  0,  0,  0],
        [ 5,  5,  5,  5],
        [10, 10, 10, 10]]]), 

array([[[ 0. ,  0.1,  0.2,  0.3],
        [ 0. ,  0.1,  0.2,  0.3],
        [ 0. ,  0.1,  0.2,  0.3]],

       [[ 0. ,  0.1,  0.2,  0.3],
        [ 0. ,  0.1,  0.2,  0.3],
        [ 0. ,  0.1,  0.2,  0.3]]])]
>>> 
>>> XYZ_indexingXY[0].shape, XYZ_indexingXY[1].shape, XYZ_indexingXY[2].shape
((3, 2, 4), (3, 2, 4), (3, 2, 4))
>>> 
>>> XYZ_indexingIJ[0].shape, XYZ_indexingIJ[1].shape, XYZ_indexingIJ[2].shape
((2, 3, 4), (2, 3, 4), (2, 3, 4))

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

>>> x = [1, 2, 3]
>>> y = [0, 5, 10, 15]
>>> z = [0, 0.1, 0.2, 0.3, 0.4]
>>> 
>>> XYZ = np.meshgrid(x, y, z)
>>> XYZ
[array([[[1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2],
        [3, 3, 3, 3, 3]],

       [[1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2],
        [3, 3, 3, 3, 3]],

       [[1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2],
        [3, 3, 3, 3, 3]],

       [[1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2],
        [3, 3, 3, 3, 3]]]),
array([[[ 0,  0,  0,  0,  0],
        [ 0,  0,  0,  0,  0],
        [ 0,  0,  0,  0,  0]],

       [[ 5,  5,  5,  5,  5],
        [ 5,  5,  5,  5,  5],
        [ 5,  5,  5,  5,  5]],

       [[10, 10, 10, 10, 10],
        [10, 10, 10, 10, 10],
        [10, 10, 10, 10, 10]],

       [[15, 15, 15, 15, 15],
        [15, 15, 15, 15, 15],
        [15, 15, 15, 15, 15]]]),
array([[[ 0. ,  0.1,  0.2,  0.3,  0.4],
        [ 0. ,  0.1,  0.2,  0.3,  0.4],
        [ 0. ,  0.1,  0.2,  0.3,  0.4]],

       [[ 0. ,  0.1,  0.2,  0.3,  0.4],
        [ 0. ,  0.1,  0.2,  0.3,  0.4],
        [ 0. ,  0.1,  0.2,  0.3,  0.4]],

       [[ 0. ,  0.1,  0.2,  0.3,  0.4],
        [ 0. ,  0.1,  0.2,  0.3,  0.4],
        [ 0. ,  0.1,  0.2,  0.3,  0.4]],

       [[ 0. ,  0.1,  0.2,  0.3,  0.4],
        [ 0. ,  0.1,  0.2,  0.3,  0.4],
        [ 0. ,  0.1,  0.2,  0.3,  0.4]]])]

Установка параметра sparse в значение True может значительно снизить затраты памяти. В результате мы получим массивы сеток сжатые до одной оси, т.е. лишь одна ось в таком массиве имеет длинну большую 1. При этом, сами массивы могут быть легко транслированы относительно друг друга:

>>> x = [1, 2, 3, 4, 5]
>>> y = [0, 5, 10, 15, 20, 25, 30, 35, 40]
>>> z = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.]
>>> 
>>> XYZ = np.meshgrid(x, y, z, sparse = True)
>>> XYZ
[array([[[1],
        [2],
        [3],
        [4],
        [5]]]),

array([[[ 0]],

       [[ 5]],

       [[10]],

       [[15]],

       [[20]],

       [[25]],

       [[30]],

       [[35]],

       [[40]]]),

array([[[ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9,  1. ]]])]
>>>
>>> 
>>> XYZ[0].shape, XYZ[1].shape, XYZ[2].shape
((1, 5, 1), (9, 1, 1), (1, 1, 11))
>>>