复数数组上的 scipy cdist 或 pdist

2024-03-30

计算两个复数之间的欧几里得距离scipy.spatial.distance.euclidean works:

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)

gives:

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这对于我的问题来说太慢了?


复数的欧几里得范数定义为该数的模,然后您可以将两个复数之间的距离定义为其差值的模。

警告的存在是因为pdist and 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 with A在上面的代码中。矩阵dist将是对称的并且对角线上为零。因此,您将在循环中执行大约两倍的操作,并且占用大约所需内存的两倍。可能它仍然比带有循环的解决方案更快(也是因为使用循环你会循环数字对)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

复数数组上的 scipy cdist 或 pdist 的相关文章

随机推荐