Какова цель meshgrid в Python / NumPy?
может кто-нибудь объяснить мне, что такое цель meshgrid
функция в Numpy? Я знаю, что он создает какую-то сетку координат для построения графика, но я не вижу прямой выгоды от этого.
Я изучаю "Python Machine Learning" от Себастьяна Рашки, и он использует его для построения границ решения. См. ввод 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)
пожалуйста, если возможно, также покажите мне много реальных примеров.
5 ответов:
цель
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
)
Предположим, у вас есть функция:
def sinus2d(x, y): return np.sin(x) + np.sin(y)
и вы хотите, например, увидеть, как это выглядит в диапазоне от 0 до 2*pi. Как бы вы это сделали? Там
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 = interp2(x_new, y_new, z_new)
и оригинальный meshgrid позволяет получить интерполяцию на исходной сетке снова:
interpolated_grid = interpolated(xx, yy)
это лишь некоторые примеры, где я использовал
meshgrid
там может быть намного больше.
собственно цель
np.meshgrid
уже упоминалось в документации:возврат координатных матриц из координатных векторов.
сделать N-D массивы координат для векторизованных оценок N-D скалярных / векторных полей над N-D сетками, учитывая одномерные массивы координат 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)
здесь
h
- это:0 2 4 0 2 4 0 2 4
и h:
0 0 0 3 3 3 6 6 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.ogrid
thesparse=True
case (я имею в виду он также поддерживает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
.или дать еще один интересный пример с помощью модели astropy (на этот раз я не очень забочусь о координатах, я просто используйте их для создания некоторые сетка):
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 и др. требуются сетки. Большинство из них работают с открытыми сетками и плотной сетки, однако некоторые работают только с одной из них.
meshgrid помогает в создании прямоугольной сетки из двух одномерных массивов всех пар точек из двух массивов.
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))
скажем, если ваша функция просто производит произведение двух элементов, то это то, как декартово произведение может быть достигнуто, эффективно для больших матрицы.
ссылка здесь