21

2つの配列間の多次元(24次元)でのユークリッド距離を計算したいと思います。numpy-Scipyを使用しています。

これが私のコードです:

import numpy,scipy;

A=numpy.array([116.629, 7192.6, 4535.66, 279714, 176404, 443608, 295522, 1.18399e+07, 7.74233e+06, 2.85839e+08, 2.30168e+08, 5.6919e+08, 168989, 7.48866e+06, 1.45261e+06, 7.49496e+07, 2.13295e+07, 3.74361e+08, 54.5, 3349.39, 262.614, 16175.8, 3693.79, 205865]);

B=numpy.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151246, 6795630, 4566625, 2.0355328e+08, 1.4250515e+08, 3.2699482e+08, 95635, 4470961, 589043, 29729866, 6124073, 222.3]);

しかし、私scipy.spatial.distance.cdist(A[numpy.newaxis,:],B,'euclidean')はユークレイダンの距離を計算するために使用しました。

しかし、それは私にエラーを与えました

raise ValueError('XB must be a 2-dimensional array.');

理解できないようです。

見上げましたscipy.spatial.distance.pdistが、使い方がわかりませんか?

それを行うための他のより良い方法はありますか?

4

7 に答える 7

24

たぶんscipy.spatial.distance.euclidean

>>> from scipy.spatial import distance
>>> distance.euclidean([1, 0, 0], [0, 1, 0])
1.4142135623730951
>>> distance.euclidean([1, 1, 0], [0, 1, 0])
1.0
于 2012-02-23T17:24:07.690 に答える
15

どちらかを使用してください

numpy.sqrt(numpy.sum((A - B)**2))

またはもっと簡単に

numpy.linalg.norm(A - B)
于 2012-02-23T14:15:36.137 に答える
8

からPython 3.8、標準ライブラリのmathモジュールとその新しいdist関数を使用できます。この関数は、2点間のユークリッド距離を返します(座標のリストまたはタプルとして指定)。

from math import dist

dist([1, 0, 0], [0, 1, 0]) # 1.4142135623730951
于 2019-01-15T10:46:42.630 に答える
7

ABは24D空間の2ポイントです。を使用する必要がありますscipy.spatial.distance.euclidean

ここにドキュメント

scipy.spatial.distance.euclidean(A, B)
于 2012-02-23T14:25:20.223 に答える
4

ユークリッド距離を計算する前述の方法とは別に、元のコードに近い方法を次に示します。

scipy.spatial.distance.cdist([A], [B], 'euclidean')

また

scipy.spatial.distance.cdist(np.atleast_2d(A), np.atleast_2d(B), 'euclidean')

np.ndarrayこれにより、L2距離を保持する1×1が返されます。

于 2012-02-23T14:29:38.507 に答える
4

上記の回答はすべてnumpyやscipyを参照しているため、reduceを使用すると本当に簡単なことができることを指摘したいと思います。

def n_dimensional_euclidean_distance(a, b):
   """
   Returns the euclidean distance for n>=2 dimensions
   :param a: tuple with integers
   :param b: tuple with integers
   :return: the euclidean distance as an integer
   """
   dimension = len(a) # notice, this will definitely throw a IndexError if len(a) != len(b)

   return sqrt(reduce(lambda i,j: i + ((a[j] - b[j]) ** 2), range(dimension), 0))

これは、次元数のすべてのjについて(a [j] --b [j])^ 2のすべてのペアを合計します(簡単にするために、これはn <2次元の距離をサポートしないことに注意してください)。

于 2017-12-12T21:29:32.560 に答える
0

独自のカスタムスクエアルートサムスクエアを書くことは必ずしも安全ではありません

numpy.sqrt(numpy.sum((A - B)**2))またはを書き込む代わりに、math.hypot、numpy.hypot、またはscipy距離関数を使用できます(i**2 + j**2)**0.5。あなたの場合、多分彼らはオーバーフローする可能性があります

参照

スピードワイズ

%%timeit
math.hypot(*(A - B))
# 3 µs ± 64.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%%timeit
numpy.sqrt(numpy.sum((A - B)**2))
# 5.65 µs ± 50.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

安全面で

アンダーフロー

i, j = 1e-200, 1e-200
np.sqrt(i**2+j**2)
# 0.0

オーバーフロー

i, j = 1e+200, 1e+200
np.sqrt(i**2+j**2)
# inf

アンダーフローなし

i, j = 1e-200, 1e-200
np.hypot(i, j)
# 1.414213562373095e-200

オーバーフローなし

i, j = 1e+200, 1e+200
np.hypot(i, j)
# 1.414213562373095e+200
于 2021-09-18T10:33:16.203 に答える