Python 如何高效地计算多时间序列的欧氏距离矩阵

Python 如何高效地计算多时间序列的欧氏距离矩阵,python,numpy,euclidean-distance,Python,Numpy,Euclidean Distance,我有如下6个时间序列数据,即t1、t2、t3、t4、t5和t6 import numpy as np series = np.array([ [0., 0, 1, 2, 1, 0, 1, 0, 0], [0., 1, 2, 0, 0, 0, 0, 0, 0], [1., 2, 0, 0, 0, 0, 0, 1, 1], [0., 0, 1, 2, 1, 0, 1, 0, 0], [0., 1, 2, 0, 0, 0, 0, 0, 0],

我有如下6个时间序列数据,即t1、t2、t3、t4、t5和t6

import numpy as np
series = np.array([
     [0., 0, 1, 2, 1, 0, 1, 0, 0],
     [0., 1, 2, 0, 0, 0, 0, 0, 0],
     [1., 2, 0, 0, 0, 0, 0, 1, 1],
     [0., 0, 1, 2, 1, 0, 1, 0, 0],
     [0., 1, 2, 0, 0, 0, 0, 0, 0],
     [1., 2, 0, 0, 0, 0, 0, 1, 1]])
我想从这6个时间序列中创建一个欧几里德距离矩阵,如6*6的格式,其中x表示相应的欧几里德距离:

     t1  t2  t3  t4  t5  t6
t1    0   x   x   x   x   x
t2    x   0   x   x   x   x
t3    x   x   0   x   x   x
t4    x   x   x   0   x   x
t5    x   x   x   x   0   x
t6    x   x   x   x   x   0
在这个问题中,我目前正在手工构建这个矩阵,如下所示:这种方法具有最高的性能

e、 例如,计算t3和t6之间的欧氏距离

def eudis(v1, v2):
    dist = [(a - b)**2 for a, b in zip(v1, v2)]
    dist = math.sqrt(sum(dist))
    return dist

eudis(t3, t6)
然而,我相信在python中可以有更简单、计算效率更高的方法来实现这一点。如果你有什么建议,请告诉我


如果需要,我很乐意提供更多细节。

您根本不需要循环,因为两个数组之间的欧几里德距离只需计算差异的元素平方,如下所示:

def euclidean_distance(v1, v2):
    return np.sqrt(np.sum((v1 - v2)**2)) 
对于距离矩阵,您有:


您根本不需要循环,因为两个数组之间的欧几里德距离只需计算差分的元素平方,如下所示:

def euclidean_distance(v1, v2):
    return np.sqrt(np.sum((v1 - v2)**2)) 
对于距离矩阵,您有:

还可以使用获取距离矩阵:

from scipy.spatial.distance import pdist, squareform
squareform(pdist(series))
性能比较和解决方案:

因此,对于相对较小的数据集(最多20个系列,200个元素),每个pdist最快,对于较大的数据集,欧几里得偏差表现得更好。纯numpy的速度通常较慢,并且可能无法为大型数据集分配中间数组。 使用np.random.randint0,100,n,10*n.astype'int16',numpy 1.17.4,scipy 1.4.1,sklearn 0.23.1,python 3.8.2,Win10 64位进行测试。

您还可以使用来获取距离矩阵:

from scipy.spatial.distance import pdist, squareform
squareform(pdist(series))
性能比较和解决方案:

因此,对于相对较小的数据集(最多20个系列,200个元素),每个pdist最快,对于较大的数据集,欧几里得偏差表现得更好。纯numpy的速度通常较慢,并且可能无法为大型数据集分配中间数组。
使用np.random.randint0,100,n,10*n.astype'int16',numpy 1.17.4,scipy 1.4.1,sklearn 0.23.1,python 3.8.2,Win10 64位进行测试。

您可以在一行中用简单的numpy创建距离矩阵,不需要其他任何东西

np.sqrt(((series[:,None,:] - series)**2).sum(axis=2))

你可以在一行中用简单的numpy创建一个距离矩阵,你不需要其他任何东西

np.sqrt(((series[:,None,:] - series)**2).sum(axis=2))

嗨,EmJ!这对你有帮助吗?更具体地说,如何使用?我并没有对它进行基准测试,但我认为numpy是非常优化的,可以进行评估。嗨,EmJ!这对你有帮助吗?更具体地说,如何使用?我没有对它进行基准测试,但我认为numpy在评估时已经进行了很大的优化。非常好的解决方案,但对于较大的时间序列,您可能会遇到内存问题您是对的,对于较大的序列,它的可伸缩性很差。非常好的解决方案,但对于较大的时间序列,您可能会遇到内存问题您是对的,对于更大的系列,它的伸缩性很差。非常感谢您的比较。因为我有一个更大的数据集,所以您提供的见解非常有用。谢谢:非常感谢你的比较。因为我有一个更大的数据集,所以您提供的见解非常有用。谢谢:谢谢你的回答。从@Stef的比较来看,对于较大的数据集,这是最快的。谢谢:谢谢你的回答。从@Stef的比较来看,对于较大的数据集,这是最快的。谢谢您: