python中是否有类似于scipy.spatial.distance.cdist的东西,但用于位移(fast)?
几周来,我一直在研究一个代码,并一直试图通过使用cdist而不是多级for循环来计算矩阵中每个点之间的距离来加速它 我想要的是:python中是否有类似于scipy.spatial.distance.cdist的东西,但用于位移(fast)?,python,numpy,scipy,scipy-spatial,Python,Numpy,Scipy,Scipy Spatial,几周来,我一直在研究一个代码,并一直试图通过使用cdist而不是多级for循环来计算矩阵中每个点之间的距离来加速它 我想要的是: from scipy.spatial.distance import cdist import numpy as np a=np.array([[1],[2],[3]]) cdist(a,a, lambda u,v: u-v) 然而,我的问题是,在我的研究背景下,a相当大,在cdist中使用自定义lambda函数要比cdist(a,
from scipy.spatial.distance import cdist
import numpy as np
a=np.array([[1],[2],[3]])
cdist(a,a, lambda u,v: u-v)
然而,我的问题是,在我的研究背景下,a相当大,在cdist中使用自定义lambda函数要比cdist(a,a)慢很多(~2个数量级),但这只能给出正值。i、 实际上,我必须计算15000次,其中a有1000个元素,所以这些元素非常重要
注:cdist(a,a)没有给出所需的输出,因为它都是正值
[[0. 1. 2.]
[1. 0. 1.]
[2. 1. 0.]]
我希望你们能给我一些建议,告诉我如何从cdist创建所需的有符号输出,但要比使用lambda函数更快
谢谢大家! 根据您的距离度量和数据类型,您有不同的选择: 对于您的特定情况,如果数据是
1D
和u-v |=((u-v)^2)^(1/2)
,您可以利用您的知识,即距离矩阵的上下三角形在绝对值上相等,并且仅在符号方面不同,因此可以避免使用自定义距离函数:
d = cdist(a, a)
triu_bool = np.triu(np.ones((n_samples, n_samples), dtype=bool))
triu_bool[range(n_samples), range(n_samples)] = False
d[triu_bool] *= -1
# [[ 0. -1. -2.]
# [ 1. 0. -1.]
# [ 2. 1. 0.]]
在我看来,更普遍、更好的方法是简单地使用numpys
broadcasting()。
下面是一个u-vu-v
的示例:
# Generate data
n_dim = 3
n_samples = int(1.5e4)
arr = np.concatenate([np.arange(n_samples)[:, np.newaxis]] * n_dim, axis=-1)
# array([[ 0, 0, 0],
# [ 1, 1, 1],
# [ 2, 2, 2],
# ...,
# [14997, 14997, 14997],
# [14998, 14998, 14998],
# [14999, 14999, 14999]])
# u - v
d = arr[:, np.newaxis, :] - arr[np.newaxis, :, :]
# (n_samples, n_samples, n_dim)
对于对称距离测量,一半的计算是不必要的。但根据我的经验,这仍然比仅将计算应用于上三角形或类似对象要快。根据您的距离度量和数据类型,您有不同的选择: 对于您的特定情况,如果数据是
1D
和u-v |=((u-v)^2)^(1/2)
,您可以利用您的知识,即距离矩阵的上下三角形在绝对值上相等,并且仅在符号方面不同,因此可以避免使用自定义距离函数:
d = cdist(a, a)
triu_bool = np.triu(np.ones((n_samples, n_samples), dtype=bool))
triu_bool[range(n_samples), range(n_samples)] = False
d[triu_bool] *= -1
# [[ 0. -1. -2.]
# [ 1. 0. -1.]
# [ 2. 1. 0.]]
在我看来,更普遍、更好的方法是简单地使用numpys
broadcasting()。
下面是一个u-vu-v
的示例:
# Generate data
n_dim = 3
n_samples = int(1.5e4)
arr = np.concatenate([np.arange(n_samples)[:, np.newaxis]] * n_dim, axis=-1)
# array([[ 0, 0, 0],
# [ 1, 1, 1],
# [ 2, 2, 2],
# ...,
# [14997, 14997, 14997],
# [14998, 14998, 14998],
# [14999, 14999, 14999]])
# u - v
d = arr[:, np.newaxis, :] - arr[np.newaxis, :, :]
# (n_samples, n_samples, n_dim)
对于对称距离测量,一半的计算是不必要的。但根据我的经验,这比只对上三角形或类似的东西进行计算要快。这解决了我的问题,我把它标记为已经这样做了。非常感谢。这解决了我的问题——我把它标记为已经这样做了。非常感谢。