3

numpy 配列内のベクトルのペアのすべての順列の違いを取得したい。

私の特定の使用例では、これらのベクトルはオブジェクトのリストの 3D 位置ベクトルです。

したがって、 、、およびが 3 次元ベクトルである配列r = [r1, r2, r3]がある場合、次のものが必要です。r1r2r3

[[r1-r1 r1-r2 r1-r3]
 [r2-r1 r2-r2 r2-r3]
 [r3-r1 r3-r2 r3-r3]]

-op が要素ごとにベクトルに適用される場所。

基本的に、これに相当するベクトル:

>>> scalars = np.arange(3)
>>> print(scalars)
[0 1 2]

>>> result = np.subtract.outer(scalars, scalars)
>>> print(result)
[[ 0 -1 -2]
 [ 1  0 -1]
 [ 2  1  0]]

ただし、outer関数は、減算の前にベクトルの配列を平坦化し、それを再形成するようです。例えば:

>>> vectors = np.arange(6).reshape(2, 3) # Two 3-dimensional vectors
>>> print(vectors)
[[0 1 2]
 [3 4 5]]

>>> results = np.subtract.outer(vectors, vectors)
>>> print(results.shape)
(2, 3, 2, 3)

私が期待している結果は次のとおりです。

>>> print(result)
[[[ 0  0  0]
  [-3 -3 -3]]
 [[ 3  3  3]
  [ 0  0  0]]]

>>> print(result.shape)
(2, 2, 3)

配列を反復せずに上記を達成できますか?

4

3 に答える 3

3

簡潔な答え:

ベクトルの「ペアごとの外部減算」を行う (ほぼ) 純粋な Python の方法はr次のとおりです。

np.array(map(operator.sub, *zip(*product(r, r)))).reshape((2, 2, -1))

したがって、基本的にproduct関数を使用してリスト項目のすべての可能なペアを取得し、unzipそれらを使用して 2 つの個別のリストを取得し、mapそれらを減算することができますoperatorreshape最後に、通常どおりにできます。

ステップバイステップ:

必要なすべてのライブラリと中間結果の出力を含む段階的な例を次に示します。

import numpy as np
from itertools import product
import operator

r = np.arange(6).reshape(2, 3)

print "Vectors:\n", r
print "Product:\n", list(product(r, r))
print "Zipped:\n", zip(*product(r, r))
print "Mapped:\n", map(operator.sub, *zip(*product(r, r)))
print "Reshaped:\n", np.array(map(operator.sub, *zip(*product(r, r)))).reshape((2, 2, -1))

出力:

Vectors:
[[0 1 2]
 [3 4 5]]
Product:
[(array([0, 1, 2]), array([0, 1, 2])), (array([0, 1, 2]), array([3, 4, 5])), (array([3, 4, 5]), array([0, 1, 2])), (array([3, 4, 5]), array([3, 4, 5]))]
Zipped:
[(array([0, 1, 2]), array([0, 1, 2]), array([3, 4, 5]), array([3, 4, 5])), (array([0, 1, 2]), array([3, 4, 5]), array([0, 1, 2]), array([3, 4, 5]))]
Mapped:
[array([0, 0, 0]), array([-3, -3, -3]), array([3, 3, 3]), array([0, 0, 0])]
Reshaped:
[[[ 0  0  0]
  [-3 -3 -3]]

 [[ 3  3  3]
  [ 0  0  0]]]

(サンプル配列を作成するには、次元2を切り替える必要があることに注意してください。)3

于 2014-08-23T09:40:44.773 に答える
3

(ここで私自身の質問に答えます)

Numpy を使用したアプローチを次に示します。

import numpy as np

N = 2
r = np.arange(N * 3).reshape(N, 3)

left = np.tile(r, N).reshape(N, N, 3)
right = np.transpose(left, axes=[1, 0, 2])

result = left - right
print result

これは、内次元のサイズが 3 の任意の 2D 配列で機能するようですが、ほとんど試行錯誤で行ったので、100% 確実ではありません。

于 2014-08-23T11:21:31.267 に答える