我是Python的新手,我需要实现一个聚类算法 . 为此,我需要计算给定输入数据之间的距离 .
考虑以下输入数据 -
[[1,2,8],
[7,4,2],
[9,1,7],
[0,1,5],
[6,4,3]]
我想在这里实现的是,我想计算[1,2,8]与所有其他点的距离,并找到距离最小的点 .
我必须为所有其他要点重复这一点 .
我试图用FOR循环实现它,但我确信SciPy / NumPy必须有一个函数可以帮助我有效地实现这个结果 .
我在线查看,但'pdist'命令无法完成我的工作 .
有人可以指导我吗?
TIA
4 回答
使用
np.linalg.norm
结合广播(numpy外部减法),你可以做到:a[:,None]
将新轴插入a
,a - a[:,None]
然后由于广播而逐行减法 .np.linalg.norm
计算最后一个轴上的np.sqrt(np.sum(np.square(...)))
:例如,元素
[0,1]
,_[0,2]
对应于:分别 .
这是使用SciPy's cdist的一种方法 -
样品运行 -
Runtime test
其他工作方法 -
时间点
10,000
点 -Further performance boost
有eucl_dist包(免责声明:我是它的作者),其中包含计算欧几里德距离的各种方法,这些方法比
SciPy's cdist
更有效,特别是对于大型数组 .因此,利用它,我们会有一个更高性能的,像这样 -
计时 -
我建议使用
pdist
和squareform
来自scipy.spatial.distance
考虑以下几点:
如果要在点
[1,2,8]
和其他点之间显示 all distances :我想在点
[1,2,8]
和最近点之间显示 shortest distance :[0]
是您第一点的索引([1,2,8]
)[1]
是第二个最小值的索引(避免零)如果要显示
[1,2,8]
最近点的 index :From this thread's您可以在那里使用 e_dist 功能并获得相同的结果 .
Addendum
Timing :在我记忆匮乏的笔记本电脑上,我只能用比@Psidom使用他的 norm_app 函数更小的样本进行比较 .
a = np.random.randint(0,9,(5000,3))
%timeit norm_app(a)每循环1.91 s±13.5 ms(平均值±标准偏差,7次运行,每次1次循环)
%timeit e_dist(a,a)每循环631 ms±3.64 ms(平均值±标准偏差,7次运行,每次循环1次)