2017-04-25 9 views
0

私は2つのベクトル(1D配列)または異なるサイズを持っています。私はそれらの各点間の距離(ここでは差)を計算したい、すなわち、長いベクトルlの最初の点と短いベクトルvの各点との差、長いベクトルの2番目の点など真の場合、ブール値行列のインデックスの行/列にアクセス

結果を[len(l), len(l)-len(v)+1]アレイ(d)に保存したいとします。そうするために、私はフィルターマトリックスを使用することを考えていました(これは必須ではありません)。

import numpy 
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
v = [1, 2, 3, 4] 
nc, nr = len(l)-len(v)+1, len(l) # n_col, n_rows 
x = numpy.array([[i-j for j in range(nc)] for i in range(nr)]) 
filter = ((x >= 0) & (x < len(v))) 
d = numpy.zeros((nr, nc)) 

だから私のfilter行列は次のとおりです。

True値は私が期待する非ゼロ値を表し
[[ True False False False False False False] 
[ True True False False False False False] 
[ True True True False False False False] 
[ True True True True False False False] 
[False True True True True False False] 
[False False True True True True False] 
[False False False True True True True] 
[False False False False True True True] 
[False False False False False True True] 
[False False False False False False True]] 

dの値をフィルタ(たとえばd[filter] = 2)で変更することはできますが、x番目の点をlといい、y番目の点はvではありません。

注意:私はを呼びたいと思っているインデックスである[0 1 0 2 1 0 3 2 1 0 3 2 1 0 3 2 1 0 3 2 1 0 3 2 1 3 2 3]を返すことに気づきました。しかし、理解されるであろうエラー(TypeError: only integer arrays with one element can be converted to an index

filterTrue又は(フィルタ行列を伴うまたは伴わない)別の溶液である行/列のインデックスにアクセスする方法上の任意のヘルプv[x[filter]]返します。

出力は次のようになります。

[[ l[0]-v[0] 0  0   0   0   0   0] 
    [ l[1]-v[1] l[1]-v[0] 0   0   0   0   0] 
    [ l[2]-v[2] l[2]-v[1] l[2]-v[0] 0   0   0   0] 
    [ l[3]-v[3] l[3]-v[2] l[3]-v[1] l[3]-v[0] 0   0   0] 
    [ 0   l[4]-v[2] l[4]-v[2] l[4]-v[1] l[4]-v[0] 0   0] 
    [ 0   0  l[5]-v[3] l[5]-v[2] l[5]-v[1] l[5]-v[0] 0] 
    [ 0   0   0  l[6]-v[3] l[6]-v[2] l[6]-v[1] l[6]-v[0]] 
    [ 0   0   0   0  l[7]-v[3] l[7]-v[2] l[7]-v[1]] 
    [ 0   0   0   0   0  l[8]-v[3] l[8]-v[5]] 
    [ 0   0   0   0   0   0  l[9]-v[3]]] 
+0

入力例に適した出力は何ですか? – Allen

+0

'numpy.where'を使用してください。 – MaxNoe

+0

@Allen、質問の最後に出力を追加しました。 @MaxNoe、私は 'numpy.where'をこの場合使用する方法を見ていません、より詳細を教えてくださいできますか? – Nuageux

答えて

0

アレンの答えに基づいて、私は所望の出力を得ることができました。

[[ 0. 0. 0. 0. 0. 0. 0.] 
[ 0. 1. 0. 0. 0. 0. 0.] 
[ 0. 1. 2. 0. 0. 0. 0.] 
[ 0. 1. 2. 3. 0. 0. 0.] 
[ 0. 1. 2. 3. 4. 0. 0.] 
[ 0. 0. 2. 3. 4. 5. 0.] 
[ 0. 0. 0. 3. 4. 5. 6.] 
[ 0. 0. 0. 0. 4. 5. 6.] 
[ 0. 0. 0. 0. 0. 5. 6.] 
[ 0. 0. 0. 0. 0. 0. 6.]] 

このコードは最適から、残念ながら遠いです:返す

arr = numpy.asarray(l) - numpy.asarray(v)[:,None] 
for i in range(d.shape[1]): 
    d[i:i+len(v),i] = numpy.diagonal(arr[:,i:i+len(v)]) 

0

は、VとLの間のペアワイズ距離すなわち、これはあなたの希望の出力か?

np.asarray(v)[:,None] - np.asarray(l) 
Out[679]: 
array([[ 0, -1, -2, ..., -7, -8, -9], 
     [ 1, 0, -1, ..., -6, -7, -8], 
     [ 2, 1, 0, ..., -5, -6, -7], 
     [ 3, 2, 1, ..., -4, -5, -6]]) 
+0

ありがとうございました。より大きいアルゴリズムの一部としてこの結果を使用できるようにするには、対角ブロックの行列形状が必要です。だからあなたもそれについて何か考えがあるなら、それは素晴らしいでしょう。 – Nuageux

0

これは目的の出力と一致しますか?

x*filter 
Out[710]: 
array([[0, 0, 0, ..., 0, 0, 0], 
     [1, 0, 0, ..., 0, 0, 0], 
     [2, 1, 0, ..., 0, 0, 0], 
     ..., 
     [0, 0, 0, ..., 3, 2, 1], 
     [0, 0, 0, ..., 0, 3, 2], 
     [0, 0, 0, ..., 0, 0, 3]]) 
+0

形状はyes、値はnoです。たとえば、最後の行/最後の列は '3 [9] -v [3] = 10-4 = 6でなく3でなければなりません。 – Nuageux

関連する問題