我有两个numpy矩阵X和Y分别代表某个d维空间中的一组点。我想计算从X中的每个点到Y中的每个点的所有欧几里得距离。scipy provides the function cdist确实做到了这一点,但有一个陷阱:有些点包含NaN形式的缺失值。我希望距离运算忽略NaN条目,例如,如果我正在计算以下两个点之间的距离
a = [1, 3, nan]
b = [2, nan, 4]
然后我将忽略第二维和第三维,从而得到sqrt((1-2)**2) = 1
的距离。
不幸的是,在此设置中,只要在一对点中找到单个NaN,cdist就会返回NaN距离。 euclidean_distances function in scikit-learn
也是如此当然可以编写一个双循环来执行所有必需的操作,但是由于X和Y是大型矩阵,因此结果太慢了。因此,基于numpy / scipy的解决方案将是理想的。
numpy确实包含一些机制,例如masked arrays,这些机制允许执行忽略NaN值的操作,但是scipy似乎忽略了这些掩码。
执行此操作的有效方法是什么?
答案 0 :(得分:3)
最简单的方法是使用标准的欧几里德距离公式,但将sum
替换为nansum
np.sqrt(np.nansum((X - Y)**2))
我怀疑您会得到比这更容易的东西(您必须自己进行广播,因为您只提供了1d输入)。标准做法是nan
始终通过计算进行。
答案 1 :(得分:1)
使用@Daniel F的建议,您可以像这样使用cdist:
cdist(XA, XB, lambda u, v: np.sqrt(np.nansum((u-v)**2)))
例如:
import numpy as np
from scipy.spatial.distance import cdist, squareform
a = np.array([1, 3, np.nan])
b = np.array([2, np.nan, 4])
print(np.sqrt(np.nansum((a-b)**2)))
输出:
1.0
上面的示例只是为了演示lambda函数的作用。