실제로 그 목적은 np.meshgrid
문서에 이미 언급되어 있습니다.
np.meshgrid
좌표 벡터에서 좌표 행렬을 반환합니다.
1 차원 좌표 배열 x1, x2, ..., xn이 주어지면 ND 그리드에서 ND 스칼라 / 벡터 필드의 벡터화 된 평가를 위해 ND 좌표 배열을 만듭니다.
따라서 기본 목적은 좌표 행렬을 만드는 것입니다.
당신은 아마 자신에게 물었다 :
좌표 행렬을 만들어야하는 이유는 무엇입니까?
Python / NumPy를 사용하여 좌표 행렬이 필요한 이유는 좌표가 0으로 시작하고 순수한 양의 정수인 경우를 제외하고는 좌표에서 값으로의 직접적인 관계가 없기 때문입니다. 그런 다음 배열의 인덱스를 인덱스로 사용할 수 있습니다. 그러나 그렇지 않은 경우 데이터와 함께 좌표를 저장해야합니다. 그것이 그리드가 들어오는 곳입니다.
데이터가 다음과 같다고 가정하십시오.
1 2 1
2 5 2
1 2 1
그러나 각 값은 가로 2km, 세로 3km를 나타냅니다. 원점이 왼쪽 상단이고 사용 가능한 거리를 나타내는 배열을 원한다고 가정하십시오.
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.ogrid
sparse=True
sparse
np.meshgrid
np.meshgrid
np.ogrid
np.mgrid
예를 들어, 2 차원 격자의 경우와 matplotlib.pyplot.imshow
는 첫 번째 반환 항목의 이름을 의미가 np.meshgrid
x
두 번째 하나를 y
그것을위한 다른 방법으로 주위 동안 np.mgrid
하고 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]])
이것은 이미 좌표, 특히 2D 플롯의 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")
>>> 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에만 국한되지 않고 임의의 차원에서 작동합니다 (파이썬에서 함수에 부여되는 최대 인수 수와 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.]])
응용
목적에 대해 구체적으로 물었고 실제로 이러한 그리드는 좌표계가 필요한 경우 매우 유용합니다.
예를 들어 거리를 2 차원으로 계산하는 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에) 그리드를 필요로한다. 이들 중 대부분은 개방형 그리드 및 고밀도 그리드에서 작동하지만 일부는 이들 중 하나에서만 작동합니다.
xx
과에 대해서는 설명하지 않았습니다yy
. 나를 위해 신비한 부분은 왜 그 결과 쌍과 결과가 반환되는지였습니다. Hai Phan의 대답은 그 점에서 편리합니다. 플롯은 두 가지 매개 변수를 원하기 때문에 편의상 그렇게한다고 생각합니다.