如何计算向量集合之间的成对欧氏距离

How to calculate pairwise Euclidean distance between a collection of vectors

我有一个这样的 pandas 数据框。其中索引为 pd.DatetimeIndex,列为时间序列。

x_1 x_2 x_3
2020-08-17 133.23 2457.45 -4676
2020-08-18 -982 -6354.56 -245.657
2020-08-19 5678.642 245.2786 2461.785
2020-08-20 -2394 154.34 -735.653
2020-08-20 236 -8876 -698.245

我需要计算所有列之间的欧氏距离。即,(x_1 - x_2)、(x_1 - x_3)、(x_2 - x_3) 和 return像这样的方形数据框: (请注意table中的值只是一个例子,并不是欧式距离的实际结果)

x_1 x_2 x_3
x_1 0 123 456
x_2 123 0 789
x_3 456 789 0

我尝试了 this 资源,但我不知道如何传递我的 df 的列。如果理解正确,该示例将行作为系列传递以计算 ED。

实现此目的的明确方法是:

from itertools import combinations

import numpy as np

dist_df = pd.DataFrame(index=df.columns, columns=df.columns)

for col_a, col_b in combinations(df.columns, 2):
    dist = np.linalg.norm(df[col_a] - df[col_b])
    dist_df.loc[col_a, col_b] = dist
    dist_df.loc[col_b, col_a] = dist

print(dist_df)

产出

              x_1           x_2           x_3
x_1           NaN  12381.858429   6135.306973
x_2  12381.858429           NaN  12680.121047
x_3   6135.306973  12680.121047           NaN

如果您想要 0 而不是 NaN,请使用 DataFrame.fillna:

dist_df.fillna(0, inplace=True)

以下代码适用于任意数量的列。

设置

df = pd.DataFrame(
    {
        "x1":[133.23, -982, 5678.642, -2394, 236],
        "x2":[2457.45, -6354.56, 245.2786, 154.34, -8876],
        "x3":[-4676, -245.657, 2461.785, -735.653, 698.245],
    }
)

解决方案

import numpy as np

aux = np.broadcast_to(df.values,  (df.shape[1], *df.shape))
result = np.sqrt(np.square(aux - aux.transpose()).sum(axis=1))

result 是一个 numpy.array

如果您愿意,可以将其包装在数据框中

pd.DataFrame(result, columns=df.columns, index=df.columns)

              x1            x2            x3
x1      0.000000  12381.858429   6081.352512
x2  12381.858429      0.000000  13622.626775
x3   6081.352512  13622.626775      0.000000

为什么这种方法有效超出了我愿意深入的范围并且需要强大的数学背景。您需要决定什么对您更重要:速度,还是 readability/understandability.