1

私は今週numpyを使い始めたばかりで、非常に混乱しています。通常の python 関数とは大きく異なるようです。

1000X6 の形状の配列では、配列内の行ごとに移動し、たとえば正三角形をチェックする方法があります。各行にトリプルがあり、各ポイントに 2 つの整数があるように、6 つの列があります。

import numpy as np
pnts = np.random.randint(0,50,(1000, 6))

また、次のような 3 つの配列を作成する方がよいと考えました。

import numpy as np
A = np.random.random((10,2))
B = np.random.random((10,2))
C = np.random.random((10,2))

順序付きペアを作成し、アルゴリズムを使用して三角形を見つけます。

順序付けられたペアの 1000 個のトリプルを表す配列を作成するより良い方法はありますか?たとえば、正三角形のように、その配列で三角形を見つけるにはどうすればよいですか?

私は今、いくつかの変更を加えました。x 座標と y 座標の 2 つの配列を作成しました。

x = np.random.randint(0,10,(3,1000))
y = np.random.randint(0,10,(3,1000))

############ 質問への追加 ############

各三角形の辺の長さと角度を見つける、一致する各 x 座標と y 座標を取得するアルゴリズムがあります。投稿しますが、コードが多すぎます。また、角度と辺の長さを使用して、不等辺、等辺、右二等辺、および非右二等辺を見つける関数もあります。

私の質問は、インデックスに関連するものになりました。例として再び正三角形を使用します。

E = np.column_stack((ACXY,ABXY,CBXY))
ES = np.logical_and(E[:,0] == E[:,1], E[:,1] == E[:,2])

私は正三角形を見つけるためにこれを持っています。

- ACXY = the distance from point A to C
- ABXY = the distance from point A to B
- CBXY = the distance from point C to B

正三角形であるすべての座標トリプルを取得し、それらにインデックスを付けて、E_Tri という新しい配列に配置できるようにしたいと考えています。ブール値を作成する関数は必要ないと思います。If: else: ステートメントの方が良い方法かもしれないと思いました。

また、これも役立つ場合がありますE = np.column_stack((ACXY,ABXY,CBXY)) 。(E) の配列を理解するために表示します。

[[  4.           4.47213595   7.21110255]
 [  3.60555128   2.23606798   5.83095189]
 [  2.23606798   9.05538514   8.54400375]
 ..., 
 [  3.60555128   9.05538514   6.08276253]
 [  8.94427191   8.54400375   1.        ]
 [ 10.63014581   1.          10.        ]]

Eはそのようになります。うまくいけば、これは理にかなっています。そうでない場合は、私に知らせてください。

質問に追加するだけでは機能しませんが、おそらくこのようなものです。

E = np.column_stack((ACXY,ABXY,CBXY))
equilateral = [] 
def E_Tri(E):
    if E[:,0] == E[:,1] and E[:,1] == E[:,2]:
        equilateral.append(E_Tri)
    else:
        return E
4

1 に答える 1

3

データの保存方法については十分に説明しましたが、アルゴリズムについては説明しませんでした。たとえば、「この 3 つの (x,y) 点 P1..P3 の集合は正三角形ですか?」という質問に答えたい場合、次のように定式化できます。

dist(P1,P2) == dist(P2,P3) == dist(P3,P1)

dist(P1,P2)ピタゴラスの定理を使用する場所:

sqrt((P1.x - P2.x)**2 + (P1.y - P2.y)**2)

ただし、sqrt()は不要であることに注意してください。これは、3 本の脚すべてが同じ長さであるかどうかだけを気にするためです (もしそうであれば、それらの正方形も同じになります)。

NumPy では、すべてを並列化できる方法で行いたいと考えています。したがって、1000 個の三角形を表す 1000x6 の配列がある場合、一度に 1000 個の要素に対してすべての操作を行う必要があります。配列が A と呼ばれ、その列が次の場合:

P1.x, P1.y, P2.x, P2.y, P3.x, P3.y

次に、最初の操作は次のとおりです。

A[0] - A[2] # P1.x - P2.x
A[1] - A[3] # P1.y - P2.y
A[2] - A[4]
A[3] - A[5]
A[4] - A[0]
A[5] - A[1]

より簡潔に書くことができます:

R = A - np.roll(A, -2, axis=0) # 1000x6 array of all differences

これが完了すると、これらの 1000x6 の結果をすべて一度に 2 乗して、1000x6 の配列 R を取得し、そこから x と y のペアを追加して距離の 2 乗を取得できます。

R[0] + R[1] # (P1.x - P2.x)**2 + (P1.y - P2.y)**2
R[2] + R[3]
R[4] + R[5]

つまり、次のようになります。

S = R[0::2] + R[1::2] # three column-wise additions at once

これにより、1000x3 の距離の正方形の配列 S が得られます。次に、各行の列がすべて等しいかどうかを確認します。

np.logical_and(S[0] == S[1], S[1] == S[2])

これにより、各行が正三角形であるかどうかを示す 1000x1 ブール値ベクトルが得られます。

行ごとに繰り返し行ったことがないことに注意してください。これは、NumPy でこれを行うと、列単位の操作を行うよりもはるかに遅いためです。

(6,1000)私が言うとき、配列の形状が実際にあると仮定して上記を書いたことに注意してください1000x6A[0]これは (の代わりに)表記の便宜のA[:,0]ためであり、NumPy はデフォルトで行優先順を使用するため、列を操作するときにより効率的であるためです。必要に応じてデータを入力できnp.transpose()ます。

したがって、最終的には次のとおりです。

A = pnts.T
R = np.square(A - np.roll(A, -2, axis=0))
S = R[0::2] + R[1::2] # 1000x3 squares of distances
np.logical_and(S[0] == S[1], S[1] == S[2]) # 1000 True/False results
于 2016-04-22T04:47:41.273 に答える