1

私は scipy を初めて使用しますが、最近、cdist距離を計算するために独自のカスタム関数をどこに渡すことができるかについて学びました。ただし、cdist個々のポイント間の距離のみを計算します (したがって、カスタム関数は 2 つのポイント間の距離を計算する必要があります)。これはほとんどの場合に機能しますが、私の場合、距離はポイントのグループ間で計算されます。(例えば、サイズ 3 のスライド ウィンドウと考えることができます)。例はこれを明確にします:

def f(*a, **kw):
    print(a, kw)
    return 0

# Consider it a set of points: [p0, p1, p2, ...]
a = numpy.array([[1,2,3],[10,11,12],[20,21,22],[30,31,32]]) 

# Consider it a set of points: [q0, q1, q2, ...]
b = numpy.array([[4,5,6],[14,15,16],[24,25,26],[34,35,36],[44,45,46]])

単純に を実行すると、 が呼び出されるscipy.spatial.distance.cdist(a, b, f)たびにf、各配列から 1 つのエントリのみが に渡されfます。したがって、関数呼び出し (および渡された値) は次のようになります。

1st call: p0, q0
2nd call: p0, q1
3rd call: p0, q2
4th call: p0, q3
5th call: p0, q4 <-- 
6th call: p1, q0
7th call: p1, q1
...and so on...

しかし、私が欲しいのは(サイズ3のウィンドウの場合)のようなものです:

1st call: [p0,p1,p2], [q0,q1,q2]
2nd call: [p0,p1,p2], [q1,q2,q3]
3rd call: [p0,p1,p2], [q2,q3,q4] <-- only till boundary
4th call: [p1,p2,p3], [q0,q1,q2]
5th call: [p1,p2,p3], [q1,q2,q3]
...and so on...

私はたくさん検索し、scipy の汎用フィルター相関関数も試しましたが、(私が理解している限り) その機能を提供していません。上記のように距離を計算する方法はありますか?

どんなアイデア/提案も大歓迎です。ありがとう

4

1 に答える 1

1

すべての距離を計算する必要があり、カスタム関数を使用しているため、利便性以外に を使用する利点はおそらくありませんcdist

まず、ポイントをウィンドウ化する必要があります。次を使用することをお勧めしas_stridedます。

import numpy as np
from numpy.lib.stride_tricks import as_strided

p = np.random.rand(4, 3)
q = np.random.rand(6, 3)
win = 3
win_p = as_strided(p, shape=(p.shape[0]-win+1, win)+p.shape[1:],
                   strides=p.strides[:1]*2+p.strides[1:])
win_q = as_strided(q, shape=(q.shape[0]-win+1, win)+q.shape[1:],
                   strides=q.strides[:1]*2+q.strides[1:])

そしていま:

>>> p
array([[ 0.8962062 ,  0.62471689,  0.1754708 ],
       [ 0.69104294,  0.66960955,  0.97012228],
       [ 0.32023353,  0.08146304,  0.7663883 ],
       [ 0.06276952,  0.1679428 ,  0.9419452 ]])
>>> win_p
array([[[ 0.8962062 ,  0.62471689,  0.1754708 ],
        [ 0.69104294,  0.66960955,  0.97012228],
        [ 0.32023353,  0.08146304,  0.7663883 ]],

       [[ 0.69104294,  0.66960955,  0.97012228],
        [ 0.32023353,  0.08146304,  0.7663883 ],
        [ 0.06276952,  0.1679428 ,  0.9419452 ]]])

ここから、明白なことを簡単に行うことができます:

ps, qs = len(win_p), len(win_q)
dist = np.empty((ps, qs))
for j, pp in enumerate(win_p) :
    for k, qq in enumerate(win_q) :
        dist[j, k] = f(pp, qq)

私が言ったように、あなたが独自の距離関数を定義したとしても、これが より遅くなるとは思いませんcdist

距離関数がどのように見えるかに応じて、ベクトル化を試みることができます。それにはおそらく shape の中間配列を作成する(ps, win, 3, qs, win, 3)必要があるため、大量のメモリが必要になる可能性が非常に高くなります。しかし、距離を測定するために考えていることを自由に投稿してください。喜んで見ていきます.

于 2013-03-30T22:08:46.543 に答える