Яке призначення мешгриду в Python / NumPy?


302

Хтось може мені пояснити, яка мета meshgridфункціонування в Numpy? Я знаю, що це створює якусь сітку координат для побудови графіків, але я не можу реально бачити прямої вигоди від цього.

Я вивчаю "Машинне навчання Python" у Себастьяна Рашка, і він використовує його для побудови меж рішення. Дивіться вхід 11 тут .

Я також спробував цей код з офіційної документації, але, знову ж таки, висновок не має для мене сенсу.

x = np.arange(-5, 5, 1)
y = np.arange(-5, 5, 1)
xx, yy = np.meshgrid(x, y, sparse=True)
z = np.sin(xx**2 + yy**2) / (xx**2 + yy**2)
h = plt.contourf(x,y,z)

Будь-ласка, будь ласка, також покажіть мені багато прикладів із реального світу.

Відповіді:


388

Мета meshgrid- створити прямокутну сітку з масиву значень x та масиву значень y.

Так, наприклад, якщо ми хочемо створити сітку, де ми маємо точку на кожне ціле значення від 0 до 4 в обох напрямках x і y. Для створення прямокутної сітки нам потрібна кожна комбінація точок xта yточок.

Це буде 25 балів, правда? Отже, якби ми хотіли створити масив x і y для всіх цих точок, ми могли б зробити наступне.

x[0,0] = 0    y[0,0] = 0
x[0,1] = 1    y[0,1] = 0
x[0,2] = 2    y[0,2] = 0
x[0,3] = 3    y[0,3] = 0
x[0,4] = 4    y[0,4] = 0
x[1,0] = 0    y[1,0] = 1
x[1,1] = 1    y[1,1] = 1
...
x[4,3] = 3    y[4,3] = 4
x[4,4] = 4    y[4,4] = 4

Це призвело б до наступних xі yматриць, таким чином, що з'єднання відповідного елемента в кожній матриці дає координати x і y точки в сітці.

x =   0 1 2 3 4        y =   0 0 0 0 0
      0 1 2 3 4              1 1 1 1 1
      0 1 2 3 4              2 2 2 2 2
      0 1 2 3 4              3 3 3 3 3
      0 1 2 3 4              4 4 4 4 4

Потім ми можемо побудувати їх, щоб перевірити, чи є вони сіткою:

plt.plot(x,y, marker='.', color='k', linestyle='none')

введіть тут опис зображення

Очевидно, що це стає дуже стомлюючим особливо для великих діапазонів xі y. Натомість meshgridможе насправді генерувати це для нас: все, що нам потрібно вказати, - це унікальність xта yцінності.

xvalues = np.array([0, 1, 2, 3, 4]);
yvalues = np.array([0, 1, 2, 3, 4]);

Тепер, коли ми дзвонимо meshgrid, ми отримуємо попередній вихід автоматично.

xx, yy = np.meshgrid(xvalues, yvalues)

plt.plot(xx, yy, marker='.', color='k', linestyle='none')

введіть тут опис зображення

Створення цих прямокутних сіток корисно для ряду завдань. У прикладі, який ви вказали у своїй публікації, це просто спосіб вибірки функції ( sin(x**2 + y**2) / (x**2 + y**2)) за діапазоном значень для xта y.

Оскільки ця функція була вибірена на прямокутній сітці, тепер функцію можна візуалізувати як "зображення".

введіть тут опис зображення

Крім того, результат тепер може бути переданий функціям, які очікують даних у прямокутній сітці (тобто contourf)


10
Ви не пояснили значення повернення xxта yy. Таємничою для мене частиною було те, чому вона повертає ту пару результатів і як вони виглядають. Відповідь Хай Фана для цього корисна. Я думаю, що це робиться для зручності, оскільки сюжет хоче таких двох параметрів.
nealmcb

2
Я не знаю - тому я шукаю цю інформацію вгору;) Тому я не кажу, що вона повинна повертати щось інше. Я просто надаю найкращі здогадки про відсутність інформації для тих, хто щойно прочитав прийняту відповідь. І якщо вам подобається, я пропоную, що ваша відповідь (що вже дуже приємно - дякую!) Була б трохи повнішою, якби ви пояснили повернені значення (як це зробив Хай), для тих із нас, хто досі спантеличений.
nealmcb

1
Щоб краще зрозуміти значення xx та yy, розгляньте твердження, що наступний код отримує такий же результат, як і np.meshgrid:xx = [xvalues for y in yvalues] yy = [[y for x in xvalues] for y in yvalues]
Метт Клейнсміт

1
Ця відповідь є заплутаною - це не ваша перша ілюстрація xта yназад? Коли ви це робите xx, yy = np.meshgrid(np.arange(4), np.arange(4)), то це зворотне значення у вас xі yв першій частині відповіді. Він відповідає порядку виходів для mgrid, але не meshgrid. Значення xxповинно зростати у напрямку x, але ваше зростає у напрямку y.
Скотт Станевич

1
@ScottStaniewicz Дякуємо за те, що ми вказали, що наше, тепер впевнене, як я зіпсував цю версію ... Оновлено!
Сувевер

249

Надано: Microsoft Excel: 

введіть тут опис зображення


6
Приємно. Fwiw, якщо ви хочете масив пар 2 x 12 посередині:XYpairs = np.vstack([ XX.reshape(-1), YY.reshape(-1) ])
деніс

5
і якщо ви хочете масив пар 12 x 2 посередині:XYpairs = np.dstack([XX, YY]).reshape(-1, 2)
barlaensdoonn

2
Гарна відповідь. Мета мешгриду - створити сітку за допомогою координати кожного тьмяного.
Хороший хлопчик

1
Що мені здається дивним, це те, що значення x і y повертаються окремо, а не об'єднуються в один масив. Якщо я хочу їх в одному масиві, мені потрібно зробити:np.vstack([XX.ravel(), YY.ravel()]).T
user3629892

64

Насправді мета np.meshgridвже згадується в документації:

np.meshgrid

Повернути матриці координат від векторів координат.

Складіть ND-координатні масиви для векторних оцінок скалярних / векторних полів ND через сітки ND, задавши одновимірні масиви координат x1, x2, ..., xn.

Тому його основна мета - створити матриці координат.

Ви, мабуть, просто запитали себе:

Чому нам потрібно створити координатні матриці?

Причина, що вам потрібні матриці координат з Python / NumPy, полягає в тому, що прямого відношення від координат до значень немає, за винятком випадків, коли ваші координати починаються з нуля і є чисто позитивними цілими числами. Тоді ви можете просто використовувати індекси масиву як індекс. Однак, коли це не так, вам потрібно якось зберігати координати поряд зі своїми даними. Ось куди заходять сітки.

Припустимо, ваші дані:

1  2  1
2  5  2
1  2  1

Однак кожне значення являє собою 2 кілометрові області по горизонталі та 3 кілометри по вертикалі. Припустимо, ваш джерело - верхній лівий кут, і ви хочете, щоб масиви відображали відстань:

import numpy as np
h, v = np.meshgrid(np.arange(3)*3, np.arange(3)*2)

де v:

array([[0, 0, 0],
       [2, 2, 2],
       [4, 4, 4]])

і h:

array([[0, 3, 6],
       [0, 3, 6],
       [0, 3, 6]])

Отже, якщо у вас є два індекси, скажімо, xі y(ось чому значення повернення meshgridзазвичай xxабо xsзамість цього xв цьому випадку я вибрав hдля горизонталі!), Тоді ви можете отримати координату x точки, координату y точки і точку значення в цій точці, використовуючи:

h[x, y]    # horizontal coordinate
v[x, y]    # vertical coordinate
data[x, y]  # value

Це набагато простіше відслідковувати координати і (що ще важливіше) ви можете передавати їх функції, які повинні знати координати.

Трохи довше пояснення

Однак np.meshgridсам по собі часто не використовується безпосередньо, здебільшого один використовує один із подібних об'єктів np.mgridабо np.ogrid. Тут np.mgridпредставляє sparse=Falseіnp.ogridsparse=True разі (я посилатися на sparseаргумент np.meshgrid). Зауважте, що існує значна різниця між np.meshgridі np.ogridта np.mgrid: Перші два повернених значення (якщо їх два чи більше) повертаються назад. Часто це не має значення, але вам слід давати змістовні імена змінних залежно від контексту.

Наприклад, у випадку двовимірної сітки та matplotlib.pyplot.imshowмає сенс назвати перший повернутий елемент np.meshgrid xта другийy тоді як це навпаки для np.mgridі np.ogrid.

np.ogrid і розріджені сітки

>>> import numpy as np
>>> yy, xx = np.ogrid[-5:6, -5:6]
>>> xx
array([[-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5]])
>>> yy
array([[-5],
       [-4],
       [-3],
       [-2],
       [-1],
       [ 0],
       [ 1],
       [ 2],
       [ 3],
       [ 4],
       [ 5]])

Як уже було сказано, результат порівняно з np.meshgrid, тому я розпакував його якyy, xx замість xx, yy:

>>> xx, yy = np.meshgrid(np.arange(-5, 6), np.arange(-5, 6), sparse=True)
>>> xx
array([[-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5]])
>>> yy
array([[-5],
       [-4],
       [-3],
       [-2],
       [-1],
       [ 0],
       [ 1],
       [ 2],
       [ 3],
       [ 4],
       [ 5]])

Це вже виглядає як координати, зокрема лінії x і y для двовимірних графіків.

Візуалізовано:

yy, xx = np.ogrid[-5:6, -5:6]
plt.figure()
plt.title('ogrid (sparse meshgrid)')
plt.grid()
plt.xticks(xx.ravel())
plt.yticks(yy.ravel())
plt.scatter(xx, np.zeros_like(xx), color="blue", marker="*")
plt.scatter(np.zeros_like(yy), yy, color="red", marker="x")

введіть тут опис зображення

np.mgrid і щільні / м'ясисті сітки

>>> yy, xx = np.mgrid[-5:6, -5:6]
>>> xx
array([[-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5]])
>>> yy
array([[-5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5],
       [-4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4],
       [-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3],
       [-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2],
       [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1],
       [ 2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2],
       [ 3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3],
       [ 4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4],
       [ 5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5]])

Це ж стосується і тут: вихідний результат обернено порівняно з np.meshgrid:

>>> xx, yy = np.meshgrid(np.arange(-5, 6), np.arange(-5, 6))
>>> xx
array([[-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5]])
>>> yy
array([[-5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5],
       [-4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4],
       [-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3],
       [-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2],
       [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1],
       [ 2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2],
       [ 3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3],
       [ 4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4],
       [ 5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5]])

На відміну від ogridцих масивів містять усі xx та yyкоординати в -5 <= xx <= 5; -5 <= yy <= 5 сітки.

yy, xx = np.mgrid[-5:6, -5:6]
plt.figure()
plt.title('mgrid (dense meshgrid)')
plt.grid()
plt.xticks(xx[0])
plt.yticks(yy[:, 0])
plt.scatter(xx, yy, color="red", marker="x")

введіть тут опис зображення

Функціональність

Це не тільки 2D, ці функції працюють для довільних розмірів (ну, існує максимальна кількість аргументів, що функціонують у Python, і максимальна кількість вимірів, яку дозволяє NumPy):

>>> x1, x2, x3, x4 = np.ogrid[:3, 1:4, 2:5, 3:6]
>>> for i, x in enumerate([x1, x2, x3, x4]):
...     print('x{}'.format(i+1))
...     print(repr(x))
x1
array([[[[0]]],


       [[[1]]],


       [[[2]]]])
x2
array([[[[1]],

        [[2]],

        [[3]]]])
x3
array([[[[2],
         [3],
         [4]]]])
x4
array([[[[3, 4, 5]]]])

>>> # equivalent meshgrid output, note how the first two arguments are reversed and the unpacking
>>> x2, x1, x3, x4 = np.meshgrid(np.arange(1,4), np.arange(3), np.arange(2, 5), np.arange(3, 6), sparse=True)
>>> for i, x in enumerate([x1, x2, x3, x4]):
...     print('x{}'.format(i+1))
...     print(repr(x))
# Identical output so it's omitted here.

Навіть якщо вони також працюють для 1D, є дві (набагато більш поширені) функції створення 1D сітки:

Крім того, startі stopаргумент він також підтримує stepаргумент (навіть складні кроки , які представляють собою ряд кроків):

>>> x1, x2 = np.mgrid[1:10:2, 1:10:4j]
>>> x1  # The dimension with the explicit step width of 2
array([[1., 1., 1., 1.],
       [3., 3., 3., 3.],
       [5., 5., 5., 5.],
       [7., 7., 7., 7.],
       [9., 9., 9., 9.]])
>>> x2  # The dimension with the "number of steps"
array([[ 1.,  4.,  7., 10.],
       [ 1.,  4.,  7., 10.],
       [ 1.,  4.,  7., 10.],
       [ 1.,  4.,  7., 10.],
       [ 1.,  4.,  7., 10.]])

Програми

Ви спеціально запитали про мету, і насправді ці сітки надзвичайно корисні, якщо вам потрібна система координат.

Наприклад, якщо у вас є функція NumPy, яка обчислює відстань у двох вимірах:

def distance_2d(x_point, y_point, x, y):
    return np.hypot(x-x_point, y-y_point)

І ви хочете знати відстань кожної точки:

>>> ys, xs = np.ogrid[-5:5, -5:5]
>>> distances = distance_2d(1, 2, xs, ys)  # distance to point (1, 2)
>>> distances
array([[9.21954446, 8.60232527, 8.06225775, 7.61577311, 7.28010989,
        7.07106781, 7.        , 7.07106781, 7.28010989, 7.61577311],
       [8.48528137, 7.81024968, 7.21110255, 6.70820393, 6.32455532,
        6.08276253, 6.        , 6.08276253, 6.32455532, 6.70820393],
       [7.81024968, 7.07106781, 6.40312424, 5.83095189, 5.38516481,
        5.09901951, 5.        , 5.09901951, 5.38516481, 5.83095189],
       [7.21110255, 6.40312424, 5.65685425, 5.        , 4.47213595,
        4.12310563, 4.        , 4.12310563, 4.47213595, 5.        ],
       [6.70820393, 5.83095189, 5.        , 4.24264069, 3.60555128,
        3.16227766, 3.        , 3.16227766, 3.60555128, 4.24264069],
       [6.32455532, 5.38516481, 4.47213595, 3.60555128, 2.82842712,
        2.23606798, 2.        , 2.23606798, 2.82842712, 3.60555128],
       [6.08276253, 5.09901951, 4.12310563, 3.16227766, 2.23606798,
        1.41421356, 1.        , 1.41421356, 2.23606798, 3.16227766],
       [6.        , 5.        , 4.        , 3.        , 2.        ,
        1.        , 0.        , 1.        , 2.        , 3.        ],
       [6.08276253, 5.09901951, 4.12310563, 3.16227766, 2.23606798,
        1.41421356, 1.        , 1.41421356, 2.23606798, 3.16227766],
       [6.32455532, 5.38516481, 4.47213595, 3.60555128, 2.82842712,
        2.23606798, 2.        , 2.23606798, 2.82842712, 3.60555128]])

Вихід був би ідентичним, якби він проходив у щільній сітці замість відкритої сітки. Можливість трансляції NumPys!

Давайте візуалізуємо результат:

plt.figure()
plt.title('distance to point (1, 2)')
plt.imshow(distances, origin='lower', interpolation="none")
plt.xticks(np.arange(xs.shape[1]), xs.ravel())  # need to set the ticks manually
plt.yticks(np.arange(ys.shape[0]), ys.ravel())
plt.colorbar()

введіть тут опис зображення

І це також коли NumPys mgridі ogridстає дуже зручним, оскільки дозволяє легко змінювати роздільну здатність ваших сіток:

ys, xs = np.ogrid[-5:5:200j, -5:5:200j]
# otherwise same code as above

введіть тут опис зображення

Однак, оскільки imshowне підтримує xта yвводить, треба змінити галочки вручну. Було б дуже зручно, якби він погодивсяx і yкоординати, правда?

Писати функції з NumPy легко, які природно діють з сітками. Крім того, в NumPy, SciPy, matplotlib є кілька функцій, які очікують, що ви перейдете в сітку.

Мені подобаються образи, тому давайте вивчимо matplotlib.pyplot.contour:

ys, xs = np.mgrid[-5:5:200j, -5:5:200j]
density = np.sin(ys)-np.cos(xs)
plt.figure()
plt.contour(xs, ys, density)

введіть тут опис зображення

Зверніть увагу, як координати вже правильно встановлені! Це не було б випадком, якби ви щойно пройшли вdensity .

Або навести ще один цікавий приклад, використовуючи моделі астропії (на цей раз я не дуже переймаюся координатами, я просто використовую їх для створення якоїсь сітки):

from astropy.modeling import models
z = np.zeros((100, 100))
y, x = np.mgrid[0:100, 0:100]
for _ in range(10):
    g2d = models.Gaussian2D(amplitude=100, 
                           x_mean=np.random.randint(0, 100), 
                           y_mean=np.random.randint(0, 100), 
                           x_stddev=3, 
                           y_stddev=3)
    z += g2d(x, y)
    a2d = models.AiryDisk2D(amplitude=70, 
                            x_0=np.random.randint(0, 100), 
                            y_0=np.random.randint(0, 100), 
                            radius=5)
    z += a2d(x, y)

введіть тут опис зображення

Хоча це лише "для зовнішнього вигляду", кілька функцій, пов'язаних з функціональними моделями та пристосуванням (наприклад scipy.interpolate.interp2d, scipy.interpolate.griddataнавіть показують приклади використання np.mgrid) в Scipy тощо, потребують сітки. Більшість із них працює з відкритими сітками та щільними сітками, проте деякі працюють лише з однією з них.


Я просто хочу сказати велику подяку за цю надзвичайно детальну відповідь. Це зробило мій день.
Jlanger

Який прекрасний спосіб відповісти на питання .... так докладно. Дякую
Біпін

h, v = np.meshgrid(np.arange(3)*3, np.arange(3)*2)- оскільки горизонталь 2 км і вертикаль 3 км не слід помножувати перший діапазон на 2, а другий на 3?
Никст

@Nixt На жаль, це не так просто. Можливо, мені доведеться ще раз перевірити цю частину відповіді. Це компроміс між транспонованим відображенням матриці та зворотним індексуванням - зазвичай ви очікуєте, що перший індекс буде горизонтальним, а другий вертикальним, але потім відображення буде переміщене. Однак це здебільшого деталь, яка, сподіваємось, не скасовує суті відповіді, яка має на меті проілюструвати причину сітки. Але я спробую переглянути це на майбутньому терміні.
MSeifert

36

Припустимо, у вас є функція:

def sinus2d(x, y):
    return np.sin(x) + np.sin(y)

і ви хочете, наприклад, побачити, як це виглядає в діапазоні від 0 до 2 * пі. Як би ти це зробив? Там np.meshgridприходить в:

xx, yy = np.meshgrid(np.linspace(0,2*np.pi,100), np.linspace(0,2*np.pi,100))
z = sinus2d(xx, yy) # Create the image on this grid

і такий сюжет виглядав би так:

import matplotlib.pyplot as plt
plt.imshow(z, origin='lower', interpolation='none')
plt.show()

введіть тут опис зображення

Тож np.meshgridпросто зручність. У принципі те саме можна зробити:

z2 = sinus2d(np.linspace(0,2*np.pi,100)[:,None], np.linspace(0,2*np.pi,100)[None,:])

але там вам потрібно знати про свої розміри (припустимо, у вас більше двох ...) та правильне мовлення. np.meshgridвсе це робить для вас.

Також meshgrid дозволяє видаляти координати разом із даними, якщо ви, наприклад, хочете зробити інтерполяцію, але виключаєте певні значення:

condition = z>0.6
z_new = z[condition] # This will make your array 1D

то як би ви зробили інтерполяцію зараз? Ви можете надати xі yфункцію інтерполяції на зразок, scipy.interpolate.interp2dтому потрібен спосіб дізнатися, які координати було видалено:

x_new = xx[condition]
y_new = yy[condition]

і тоді ви все ще можете інтерполювати з "правильними" координатами (спробуйте це без meshgrid, і у вас буде багато зайвого коду):

from scipy.interpolate import interp2d
interpolated = interp2d(x_new, y_new, z_new)

і вихідний meshgrid дозволяє отримати інтерполяцію на вихідній сітці знову:

interpolated_grid = interpolated(xx[0], yy[:, 0]).reshape(xx.shape)

Це лише кілька прикладів, де я використовував, meshgridможливо, буде набагато більше.


1
Спасибі за вашу відповідь! Самі заплутані для мене момент повертаються значення xx, yy. Було важко зрозуміти, що вони є, і чому ми використовуємо їх для обчислення функції. Здається, я це зрозумів. Ми хочемо обчислити деяку функцію на основі координат. Ми можемо написати щось подібне: for x=1:10: for y=1:10: z[x,y]=sin(x)+sin(y)Натомість обчислюємо zпо-іншому z=sin([x,x,...,x]) + sin([y,y,..y]). Виправте мене, якщо я помиляюся!
Алена Кастюкавець

Це не 100% правильний псевдо-код, але я сподіваюся, що ви бачите мою думку)
Alena Kastsiukavets

Насправді вам завжди потрібен подвійний цикл (ваш перший код). Але є різні способи досягти цього numpy: мешгрид або мовлення. Якщо ви не відкидаєте бали (див. Останню частину моєї відповіді), обидва насправді функціонально еквівалентні. Трансляція - це лише неявна петля в масштабі, що транслюється. Зауважте, що я використовував [:,None]і [None, :]включав додаткові параметри, щоб результат вийшов правильно. Ваш другий приклад більше схожий на:sin([[y],[y],..[y]])
MSeifert

Справді приємна ілюстрація. Дякуємо, що доклали багато зусиль.
натерсоз

interpolated_grid = interpolated(xx, yy)- це не працює для мене, помилка:x and y should both be 1-D arrays
Nixt

4

meshgrid допомагає у створенні прямокутної сітки з двох 1-D масивів усіх пар точок з двох масивів.

x = np.array([0, 1, 2, 3, 4])
y = np.array([0, 1, 2, 3, 4])

Тепер, якщо ви визначили функцію f (x, y) і хочете застосувати цю функцію до всіх можливих комбінацій точок з масивів 'x' та 'y', ви можете це зробити:

f(*np.meshgrid(x, y))

Скажімо, якщо ваша функція просто створює продукт з двох елементів, то таким чином можна досягти декартового продукту, ефективно для великих масивів.

Посилання звідси


1

Основна ідея

Враховуючи можливі значення x,, xs(подумайте про них як галочки на осі x ділянки) та можливі значення y ys,meshgrid генерує відповідний набір (x, y) точок сітки --- аналогічно set((x, y) for x in xs for y in yx). Наприклад, якщо xs=[1,2,3]і ys=[4,5,6], ми отримаємо набір координат{(1,4), (2,4), (3,4), (1,5), (2,5), (3,5), (1,6), (2,6), (3,6)} .

Форма повернення вартості

Однак уявлення, що meshgrid повертається, відрізняється від наведеного виразу двома способами:

По-перше , meshgridвикладає точки сітки у 2d масиві: рядки відповідають різним y-значенням, стовпці відповідають різним x-значенням --- як у list(list((x, y) for x in xs) for y in ys), що дало б такий масив:

   [[(1,4), (2,4), (3,4)],
    [(1,5), (2,5), (3,5)],
    [(1,6), (2,6), (3,6)]]

По-друге ,meshgrid повертає координати x і y окремо (тобто у двох різних numpy 2d масивах):

   xcoords, ycoords = (
       array([[1, 2, 3],
              [1, 2, 3],
              [1, 2, 3]]),
       array([[4, 4, 4],
              [5, 5, 5],
              [6, 6, 6]]))
   # same thing using np.meshgrid:
   xcoords, ycoords = np.meshgrid([1,2,3], [4,5,6])
   # same thing without meshgrid:
   xcoords = np.array([xs] * len(ys)
   ycoords = np.array([ys] * len(xs)).T

Примітка, np.meshgrid також можна створювати сітки для більших розмірів. З огляду на xs, ys і zs, ви отримаєте назад xcoords, ycoord, zcoord у вигляді 3d-масивів.meshgridтакож підтримує зворотне упорядкування розмірів, а також розріджене представлення результату.

Програми

Чому ми б хотіли такої форми виробництва?

Застосовуйте функцію в кожній точці сітки: Однією з мотивацій є те, що двійкові оператори типу (+, -, *, /, **) перевантажуються для numpy масивів як елементарних операцій. Це означає, що якщо у мене є функція, def f(x, y): return (x - y) ** 2яка працює на двох скалярах, я також можу застосувати її до двох нумерованих масивів, щоб отримати масив результатів елементів: наприклад, f(xcoords, ycoords)або наводити f(*np.meshgrid(xs, ys))наступне у наведеному вище прикладі:

array([[ 9,  4,  1],
       [16,  9,  4],
       [25, 16,  9]])

Вищий розмірний зовнішній виріб: я не впевнений, наскільки це ефективно, але ви можете отримати високомірні зовнішні вироби таким чином:np.prod(np.meshgrid([1,2,3], [1,2], [1,2,3,4]), axis=0) .

Контурні графіки в matplotlib: Я натрапив, meshgridколи досліджував малюнок контурних ділянок з matplotlib для побудови графіку меж рішення . Для цього ви створюєте сітку за допомогою meshgrid, оцінюєте функцію в кожній точці сітки (наприклад, як показано вище), а потім передаєте xcoords, ycoord та обчислювані f-значення (тобто zcoord) у функцію contourf.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.