使用scipy.spatial.distance.euclidean
计算两个复数之间的欧几里德距离有效:
import numpy
import scipy.spatial.distance
z1 = numpy.complex(numpy.cos(0), numpy.sin(0))
z2 = numpy.complex(numpy.cos(3*numpy.pi/2), numpy.sin(3*numpy.pi/2))
print scipy.spatial.distance.euclidean(z1, z2)
给出:
1.4142135623730951
然而,成对距离矩阵或两个输入数组的每对之间的距离不起作用:
A = numpy.random.uniform(size=(5,1)) + numpy.random.uniform(size=(5,1))*1j
print scipy.spatial.distance.pdist(A)
返回警告以及实际部分之间的距离:
lib/python2.7/site-packages/scipy/spatial/distance.py:107: ComplexWarning: Casting complex values to real discards the imaginary part
X = X.astype(np.double)
array([ 0.78016544, 0.66201108, 0.8330932 , 0.54355982, 0.11815436,
0.05292776, 0.23660562, 0.17108212, 0.11845125, 0.28953338])
与scipy.spatial.distance.cdist(A,A)
相同。
是否可以使用cdist或pdist计算成对距离矩阵或每对输入数组之间的距离,而不使用for循环和scipy.spatial.distance.euclidean
这对我的问题来说太慢了?
答案 0 :(得分:2)
复数的欧几里德范数被定义为数的模数,然后你可以将两个复数之间的距离定义为它们之差的模数。
警告就在那里,因为pdist
和cdist
是为N维(标量)空间设计的,其中这种距离概念没有任何意义。 (你如何处理许多维度,每个维度包含一个复数?对于标量很容易,但对于复杂的,你有几个选项)
给出两个积分:
A = numpy.random.uniform(size=(5)) + numpy.random.uniform(size=(5))*1j
B = numpy.random.uniform(size=(5)) + numpy.random.uniform(size=(5))*1j
A
的每个点与B
的每个点之间的距离可以计算为
MA = tile(A[:,newaxis],A.size)
MB = tile(B[:,newaxis],B.size)
dist = abs(MA-MB.T)
并且您将在dist[2][3]
中获得集合A
的第三个点与集合B
的第四个点之间的距离。
这非常有效,如果像@ali_m在评论中建议的那样一步完成,
dist = np.abs(A[:, None] - B[None, :])
如果您只想要单个集合A
的成对距离矩阵,则可以在上面的代码中将B
替换为A
。矩阵dist
将是对称的,并且在对角线上将为零。因此,您将在循环中进行大约两倍的操作,并且占用的内存大约是所需内存的两倍。可能它仍然比带循环的解决方案更快(也因为循环你循环数字对)