我有一个二维值矩阵。每行都是一个数据点。
data = np.array(
[[2, 2, 3],
[4, 2, 4],
[1, 1, 4]])
现在,如果我的测试点是单个1D numpy数组,如:
test = np.array([2,3,3])
我可以做一些简单的事情,比如np.sqrt(np.sum((test-data)**2,axis=1))
来计算测试点相对于所有三个数据点的距离。
但是,如果测试本身是要测试的2D点阵,那么上面的工作并没有用,我一直在使用类似的东西:
test = np.array([[2,3,3],[4,1,2]])
for i in range(len(test)):
print np.sqrt(np.sum((test[i]-data)**2,axis=1))
>>> [ 1. 2.44948974 2.44948974]
[ 2.44948974 2.23606798 3.60555128]
为了计算我的测试集中针对数据集中所有点的每个点。看起来应该有一种方法可以对整个操作进行矢量化,这样我就可以得到一个相应距离的(2,3)矩阵,而没有外部的FOR循环
(注意:虽然这个特殊的例子是关于欧几里德距离的,但我发现自己有类似的类型操作,我想对一个矩阵的所有元素和另一个矩阵的各个元素执行一个操作,所以我' m希望有一种使用Numpy设置这种性质问题的通用方法。)
答案 0 :(得分:2)
使用broadcasting来执行此操作:
from numpy.linalg import norm
norm(data-test[:,None],axis=2)
的
[ 1. 2.44948974 2.44948974]
[ 2.44948974 2.23606798 3.60555128]
一些解释。例如,用不同的形状,四点和两点来理解它更容易:
ens1 = np.array(
[[2, 2, 3],
[4, 2, 4],
[1, 1, 4],
[2, 4, 5]])
ens2 = np.array([[2,3,3],
[4,1,2]])
In [16]: ens1.shape
Out[16]: (4, 3)
In [17]: ens2.shape
Out[17]: (2, 3)
然后:
In [21]: ens2[:,None].shape
Out[21]: (2, 1, 3)
添加新维度。现在我们可以进行2X4 = 8次减法:
In [22]: (ens1-ens2[:,None]).shape
Out[22]: (2, 4, 3)
并沿着最后一个轴取标准,持续8个距离:
In [23]: norm(ens1-ens2[:,None],axis=2)
Out[23]:
array([[ 1. , 2.44948974, 2.44948974, 2.23606798],
[ 2.44948974, 2.23606798, 3.60555128, 4.69041576]])
答案 1 :(得分:1)
np.meshgrid
怎么样?
import numpy as np
data = np.array(
[[2, 2, 3],
[4, 2, 4],
[1, 1, 4]])
test = np.array([[2,3,3],
[4,1,2]])
d = np.arange(0,3)
t = np.arange(0,2)
d, t = np.meshgrid(d, t)
# print test[t]
# print data[d]
print np.sqrt(np.sum((test[t]-data[d])**2,axis=2))
输出:
[[ 1. 2.44948974 2.44948974]
[ 2.44948974 2.23606798 3.60555128]]
答案 2 :(得分:-2)
您可以使用列表理解:
result = np.array([np.sqrt(np.sum((t - data)**2, axis=1)) for t in test])