调用方法
from scipy.spatial.distance import pdist, squareform
scipy.spatial.distance.squareform(X, force='no', checks=True)
各个参数意义:
X
:一个压缩或冗余的距离矩阵。
force
:可以被设定为 "tovector"
或者 "tomatrix"
,输入将会被看作是一个距离矩阵或者距离矢量。
checks
:如果被设定为 False
,如果已知 X - X.T1
很小且 diag(X)
接近于
Y
:返回值,如果传递进入一个压缩距离矩阵,冗余的矩阵就会被返回,如果传递进入一个冗余的矩阵,压缩距离矩阵会被返回。
注意
v = squareform(X)
如果我们给予 squareform()
一个
n
×
n
n\times n
n×n 的对称距离矩阵 X
。比如二项式系数选择为 2
,那么 squareform(X)
就会返回一个
n
∗
(
n
−
1
)
/
2
n * \left(n-1\right) / 2
n∗(n−1)/2 大小的矢量
v
v
v,其中:
D
i
s
t
a
n
c
e
i
,
j
=
v
[
(
n
2
)
−
(
n
−
i
2
)
+
(
j
−
i
−
1
)
]
\mathrm{Distance}_{i, j} =v\left [ \begin{pmatrix} n \\ 2 \end{pmatrix} -\begin{pmatrix} n-i \\ 2 \end{pmatrix}+\left ( j-i-1 \right ) \right ]
Distancei,j=v[(n2)−(n−i2)+(j−i−1)]
上式表示不同点 i
与 j
之间的距离。
如果 x
是非正方形或者非对称的,就会报错。
如果给定一个
n
∗
(
n
−
1
)
/
2
n * \left(n-1\right) / 2
n∗(n−1)/2 大小的矢量
v
v
v,对于某些整数
n
>
=
1
n>=1
n>=1的编码距离,X=squareform(v) 返回一个
n
×
n
n\times n
n×n 距离矩阵 X。
X
[
i
,
j
]
X\left [ i, j \right ]
X[i,j] 与
X
[
j
,
i
]
X\left [ j, i \right ]
X[j,i] 的值被设定为:
D
i
s
t
a
n
c
e
i
,
j
=
v
[
(
n
2
)
−
(
n
−
i
2
)
+
(
j
−
i
−
1
)
]
\mathrm{Distance}_{i, j} =v\left [ \begin{pmatrix} n \\ 2 \end{pmatrix} -\begin{pmatrix} n-i \\ 2 \end{pmatrix}+\left ( j-i-1 \right ) \right ]
Distancei,j=v[(n2)−(n−i2)+(j−i−1)]
同时对角线上的元素均被设置为 0。
上面这个表达式相信大家看到都会比较懵,这里我来解释一下。矢量 D i s t a n c e i , j \mathrm{Distance}_{i, j} Distancei,j 描述了一个长度为 n n n 的线性空间中, i i i 和 j j j 之间的距离。具体来说, D i s t a n c e i , j \mathrm{Distance}_{i, j} Distancei,j 表示从向量空间中第 i i i 个向量到第 j j j 个向量所需要的步数。其中,每一步可以沿着向量空间中的任意一个向量移动,但是每个向量只能被经过一次。这里的 v v v 表示每一步的代价,也可以理解为移动单位长度所需花费的代价。
第一项
(
n
2
)
\begin{pmatrix} n \\ 2 \end{pmatrix}
(n2) 表示向量空间中总共有多少个向量对,即任意两个向量之间都需要进行移动。
第二项
(
n
−
i
2
)
\begin{pmatrix} n-i \\ 2 \end{pmatrix}
(n−i2) 表示从第
i
i
i 个向量开始,已经有多少对向量已经被移动过了,即已经不需要再移动。
第三项
(
j
−
i
−
1
)
\left ( j-i-1 \right )
(j−i−1) 表示在第二项的基础上,从第
i
i
i 个向量到第
j
j
j 个向量之间还需要经过多少对向量。将这三个部分加起来,就能得到从第
i
i
i 个向量到第
j
j
j 个向量所需的步数。
依然很抽象,那么我们来看一个示例,在阅读示例之前推荐优先阅读------Python scipy.spatial.distance.pdist() 函数的用法。
示例1
import numpy as np
from scipy.spatial.distance import pdist, squareform
x = np.array([[0, 10], [10, 10], [20, 20]])
result = pdist(x)
print(result)
square_matrix = squareform(pdist(x))
print(square_matrix)
"""
result:
[10. 22.36067977 14.14213562]
[[ 0. 10. 22.36067977]
[10. 0. 14.14213562]
[22.36067977 14.14213562 0. ]]
"""
我们可以看到 squareform()
函数实际上将我们传递进入的以为距离数组变成了也给正方形矩阵,且矩阵对应索引位置上的元素值等于两点之间的距离,而这些位置的索引值与点的索引值一致,且关于主对角线对称,对角线上的元素全部为 0
。如果我们此时将方形矩阵记作
S
S
S,比如,10.
此时位于
S
12
S_{12}
S12 与
S
21
S_{21}
S21 的位置,可以理解为原始数组 x
中第一个点和第二个点之间的距离。显然数组 x
中的第一个点坐标为 [0, 10]
,第二个点的坐标为 [10, 10]
,它们之间的距离也为 10.
。我们的说法得到了验证。
根据之前 squareform()
函数的定义说明,如果此时我们将上面得到的 square_matrix
作为参数传递进去会得到什么呢?
import numpy as np
from scipy.spatial.distance import pdist, squareform
x = np.array([[0, 10], [10, 10], [20, 20]])
result = pdist(x)
print(result)
square_matrix = squareform(pdist(x))
print(square_matrix)
print(squareform(square_matrix))
"""
result:
[10. 22.36067977 14.14213562]
[[ 0. 10. 22.36067977]
[10. 0. 14.14213562]
[22.36067977 14.14213562 0. ]]
[10. 22.36067977 14.14213562] # 最终结果
"""
我们可以看到,最终的结果又变回了压缩矩阵(一维数组)的形式。这也与我们定义中叙述的情况一致。
对于结果中的数组,它们分别对应的英文名称为:
# Condensed distance matrix
[10. 22.36067977 14.14213562]
# full distance matrix
[[ 0. 10. 22.36067977]
[10. 0. 14.14213562]
[22.36067977 14.14213562 0. ]]
如果大家觉得有用,就点个赞让更多的人看到吧~