3D numpy配列A(2133,3,3)があります。基本的にこれは3つの3Dポイントを持つ2133リストのリストです。さらに私は、3つの3Dポイントを取り、長さ3のa、b、c、x numpyの配列を持つx = f(a, b, c)
という1つの3Dポイントを返す関数を持っています。今度は、出力を形状の配列にするためにfにAを適用したい(2133,3)。だから、numpy.array([f(*A[0]),...,f(*A[2132]))
のようなものです。3D numpy配列に3引数関数を適用する
numpy.apply_along_axis
とnumpy.vectorize
を試しましたが、成功しませんでした。
def f(a, b, c, r1, r2=None, r3=None):
a = np.asarray(a)
b = np.asarray(b)
c = np.asarray(c)
if np.linalg.matrix_rank(np.matrix([a, b, c])) != 3:
# raise ValueError('The points are not collinear.')
return None
a, b, c, = sort_triple(a, b, c)
if any(r is None for r in (r2, r3)):
r2, r3 = (r1, r1)
ex = (b - a)/(np.linalg.norm(b - a))
i = np.dot(ex, c - a)
ey = (c - a - i*ex)/(np.linalg.norm(c - a - i*ex))
ez = np.cross(ex, ey)
d = np.linalg.norm(b - a)
j = np.dot(ey, c - a)
x = (pow(r1, 2) - pow(r2, 2) + pow(d, 2))/(2 * d)
y = ((pow(r1, 2) - pow(r3, 2) + pow(i, 2) + pow(j, 2))/(2*j)) - ((i/j)*x)
z_square = pow(r1, 2) - pow(x, 2) - pow(y, 2)
if z_square >= 0:
z = np.sqrt(z_square)
intersection = a + x * ex + y*ey + z*ez
return intersection
A = np.array([[[131.83, 25.2, 0.52], [131.51, 22.54, 0.52],[133.65, 23.65, 0.52]], [[13.02, 86.98, 0.52], [61.02, 87.12, 0.52],[129.05, 87.32, 0.52]]])
r1 = 1.7115
'np.vectorize'と' np.apply_along_axis'で何を試してみるのが参考になるでしょうか。また、関数fは正確に何をするのですか?ベクトル化されたバージョンで置き換えることができます。 – user2699
@ user2699私は関数fを提供しました。私は 'np.apply_along_axis'の問題は、与えられた軸に沿って1次元スライスに適用されていることです。アンパックが正しい方法で行われないので、 'np.vectorize'は動作しません。私が 'f'を書き直しても形状の配列(3,3)が得られるように、numpyを第1軸上で反復して3x3のサブ配列を取る方法を教えてください。 – patrik
これを行う自動方法はありません。単一点の代わりに点の配列で動作するように 'f'を書く必要があります。私はそれがほぼ大丈夫だと思いますが、最初の 'if'を変更する必要がありますが、' np.linalg.norm'呼び出しに 'axis'パラメータを追加し、多分もっと多くのものを' sort_triple'としますあなたの機能が適応される必要があるかもしれない場合は別です)。 Btwでは、すべての 'pow(x、2)'呼び出しを 'np.square(x)'に置き換えることを検討してください。 – jdehesa