gaussian_kde
SciPy マニュアルの2D データの操作方法の説明を理解するのが難しいことがわかりました。@endolith の例を補足するための説明を次に示します。コードをいくつかのステップに分割し、直感的ではない部分を説明するコメントを付けました。
まず、インポート:
import numpy as np
import scipy.stats as st
from matplotlib.pyplot import imshow, show
いくつかのダミー データを作成します。これらは、"X" および "Y" ポイント座標の 1 次元配列です。
np.random.seed(142) # for reproducibility
x = st.norm.rvs(loc=2, scale=1, size=2000)
y = st.norm.rvs(loc=0, scale=3, size=2000)
2-D 密度推定の場合、gaussian_kde
オブジェクトは "X" および "Y" データセットを含む 2 行の配列で初期化する必要があります。NumPy の用語では、「それらを垂直に積み重ねる」:
xy = np.vstack((x, y))
したがって、「X」データは最初の行xy[0,:]
にあり、「Y」データは 2 行目xy[1,:]
にありxy.shape
、(2, 2000)
. gaussian_kde
オブジェクトを作成します。
dens = st.gaussian_kde(xy)
推定された 2 次元密度 PDF を 2 次元グリッドで評価します。NumPy でこのようなグリッドを作成する方法は複数あります。ここでは、 @endolith の方法とは異なる (ただし機能的には同等の) アプローチを示します。
gx, gy = np.mgrid[x.min():x.max():128j, y.min():y.max():128j]
gxy = np.dstack((gx, gy)) # shape is (128, 128, 2)
gxy
は 3 次元配列で、 の[i,j]
番目の要素にgxy
は、対応する "X" 値と "Y" 値の 2 要素リストが含まれます:gxy[i, j]
の値は[ gx[i], gy[j] ]
です。
各 2 次元グリッド ポイントでdens()
(または同じことを)呼び出す必要があります。dens.pdf()
NumPy には、この目的のために非常に洗練された関数があります。
z = np.apply_along_axis(dens, 2, gxy)
つまり、callable dens
(同様に可能性があります) は3 次元配列の (3 番目の軸) にdens.pdf
沿って呼び出され、値は 2 次元配列として返されます。唯一の不具合は、 の形状が期待したものではなく、 になることです。ドキュメントには次のように記載されていることに注意してください。axis=2
gxy
z
(128,128,1)
(128,128)
out [戻り値、LD] の形状は、軸方向の次元を除いて、arr の形状と同じです。この軸は削除され、func1d の戻り値の形状に等しい新しい次元に置き換えられます。したがって、func1d がスカラーを返す場合、out は arr よりも 1 つ少ない次元になります。
ほとんどdens()
の場合、私が望んでいたスカラーではなく、長さ 1 のタプルが返されました。これは簡単に修正できるため、これ以上問題を調査しませんでした。
z = z.reshape(128, 128)
その後、画像を生成できます。
imshow(z, aspect=gx.ptp() / gy.ptp())
show() # needed if you try this in PyCharm
これが画像です。( @endolith のバージョンも実装しており、これと見分けがつかない画像が得られたことに注意してください。)
