【问题标题】:calculate euclidean distance for PCA in python在python中计算PCA的欧几里得距离
【发布时间】:2014-04-09 14:32:56
【问题描述】:

我有 3D 的 PCA numpy array as

pcar =[[xa ya za]
       [xb yb zb]
       [xc yc zc]
       .
       .
       [xn yn zn]]

其中每一行都是一个点,我从PCA 上方选择了任意两个随机行作为集群

out_list=pcar[numpy.random.randint(0,pcar.shape[0],2)]

给出 2 行的 numpy 数组。

我必须从 out_list 的每一行与 pcar 中的每一行(点)找到欧几里得距离,并将该 pcar 点添加到 out_list 集群中最近的点。

【问题讨论】:

  • 如果两个点的 x,y,z 相同会怎样?

标签: python numpy pca euclidean-distance


【解决方案1】:

Scipy 中有一个非常快速的实现:

 from scipy.spatial.distance import cdist, pdist

cdist 采用两个向量,例如您的 pchar 一个,并计算每个点之间的距离。 pdist 只会为您提供该矩阵的上三角形。

由于它们是在幕后用 C 或 Fortran 实现的,因此它们的性能非常好。

【讨论】:

【解决方案2】:

编辑 好的,我下载、安装并自学了 numpy。这是一个numpy版本

旧答案

我知道你想要一个 numpy 的答案。我的 numpy 生锈了,但由于没有其他答案,我想我会在 Matlab 中给你一个。转换应该很简单。我假设问题是概念,而不是代码。

请注意,给这只猫剥皮的方法有很多种,我只提供一种。

工作 Numpy 版本

import numpy as np

pcar = np.random.rand(10,3)

out_list=pcar[np.random.randint(0,pcar.shape[0],2)]

ol_1 = out_list[0,:]
ol_2 = out_list[1,:]

## Get the individual distances
## The trick here is to pre-multiply the 1x3 ol vector with a row of
## ones of size 10x1 to get a 10x3 array with ol replicated, so that it
## can simply be subtracted
d1 = pcar - ones( size(pcar,1))*ol_1
d2 = pcar - ones( size(pcar,1))*ol_2

##% Square them using an element-wise square
d1s = np.square(d1)
d2s = np.square(d2)

##% Sum across the rows, not down columns
d1ss = np.sum(d1s, axis=1)
d2ss = np.sum(d2s, axis=1)

##% Square root using an element-wise square-root
e1 = np.sqrt(d1ss)
e2 = np.sqrt(d2ss)

##% Assign to class one or class two
##% Start by assigning one to everything, then select all those where ol_2
##% is closer and assign them the number 2
assign = ones(size(e1,0));
assign[e2<e1] = 2

##% Separate
pcar1 = pcar[ assign==1, :]
pcar2 = pcar[ assign==2, :]

工作 Matlab 版本

close all
clear all

% Create 10 records each with 3 attributes
pcar = rand(10, 3)

% Pick two (normally at random of course)
out_list = pcar(1:2, :)

% Hard-coding this separately, though this can be done iteratively
ol_1 = out_list(1,:)
ol_2 = out_list(2,:)

% Get the individual distances
% The trick here is to pre-multiply the 1x3 ol vector with a row of
% ones of size 10x1 to get a 10x3 array with ol replicated, so that it
% can simply be subtracted
d1 = pcar - ones( size(pcar,1), 1)*ol_1
d2 = pcar - ones( size(pcar,1), 1)*ol_2

% Square them using an element-wise square
d1s = d1.^2
d2s = d2.^2

% Sum across the rows, not down columns
d1ss = sum(d1s, 2)
d2ss = sum(d2s, 2)

% Square root using an element-wise square-root
e1 = sqrt(d1ss)
e2 = sqrt(d2ss)

% Assign to class one or class two
% Start by assigning one to everything, then select all those where ol_2
% is closer and assign them the number 2
assign = ones(length(e1),1);
assign(e2<e1)=2

% Separate
pcar1 = pcar( assign==1, :)
pcar2 = pcar( assign==2, :)

% Plot
plot3(pcar1(:,1), pcar1(:,2), pcar1(:,3), 'g+')
hold on
plot3(pcar2(:,1), pcar2(:,2), pcar2(:,3), 'r+')
plot3(ol_1(1), ol_1(2), ol_1(3), 'go')
plot3(ol_2(1), ol_2(2), ol_2(3), 'ro')

【讨论】:

  • 尽管如此有用,但它并没有回答 OP 的问题,因为他们在 python 中需要它,但还是要努力
  • @EdChum 我意识到 OP 正在使用 numpy。如果问题出在概念上,那么用伪代码回答就可以了。如果伪代码可以很好,为什么不是 Matlab,它是 numpy 的第一个表亲?无论如何,我认为它不会受到伤害。
  • @EdChum 好的,我提供了一个 numpy 版本。这是 stackoverflow 和 python 的功劳,我可以下载、安装和学习足够的 numpy 以在大约 30m 内翻译我的代码!
  • @timbo 它给出了两个带有 pcar 的数组,其中包含少 1 行和另一个单行数组,这是从 pcar 中删除的数组。
  • @timbo 你不应该使用'from numpy import *',尤其是在你做了“import numpy as np”之后。除此之外,您可以通过执行“d1s = d12”和“e1 = d1ss0.5”来提高可读性,而不是使用您使用的语法。很明显,你只知道 numpy 30 分钟,但是再给它 30 分钟,你会喜欢它,再过 30 分钟你会意识到 matlab 没有意义,只是占用磁盘空间,而且钱可以花在其他东西上更好比matlab许可费;-)。欢迎来到 numpy,它会让你大吃一惊。
猜你喜欢
  • 2013-04-08
  • 2015-04-25
  • 1970-01-01
  • 1970-01-01
  • 2020-11-29
  • 2018-02-14
  • 2020-07-24
  • 2013-04-07
  • 2021-01-31
相关资源
最近更新 更多