実際にの目的np.meshgrid
はすでにドキュメントで言及されています:
np.meshgrid
座標ベクトルから座標行列を返します。
1次元座標配列x1、x2、...、xnを指定して、NDグリッド上のNDスカラー/ベクトルフィールドのベクトル化された評価のためのND座標配列を作成します。
したがって、それは主な目的が座標行列を作成することです。
あなたはたぶん自分自身に尋ねました:
なぜ座標行列を作成する必要があるのですか?
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]])
あなたは2つのインデックス、letのだと言う持っているのであれば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
及びケース(私は参照の引数)。and との間には大きな違いがあることに注意してください
。最初の2つの戻り値(2つ以上ある場合)は逆になります。多くの場合これは重要ではありませんが、コンテキストに応じて意味のある変数名を指定する必要があります。np.ogrid
sparse=True
sparse
np.meshgrid
np.meshgrid
np.ogrid
np.mgrid
例えば、2次元グリッドの場合とではmatplotlib.pyplot.imshow
、それは最初に返さ項目名前に意味をなすnp.meshgrid
x
2つ目を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に限定されず、これらの関数は任意の次元で機能します(まあ、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でも機能する場合でも、2つの(より一般的な)1Dグリッド作成関数があります。
start
and 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などの機能モデルおよびフィッティングに関連するいくつかの関数(たとえばscipy.interpolate.interp2d
、
scipy.interpolate.griddata
を使用した例を示すことさえnp.mgrid
)にはグリッドが必要です。これらのほとんどはオープングリッドとデンスグリッドで機能しますが、一部はそれらの1つでのみ機能します。
xx
とを説明していませんyy
。私にとって不思議なのは、その結果のペアが返される理由と、それらがどのように見えるかです。ハイファンの答えはそのために便利です。plotはそのような2つのパラメータを必要としているので、便宜上それを行うと思います。