来自两个独立数据帧的距离矩阵
Distance matrix from two separate data frames
我想创建一个矩阵,其中包含一个数据框的行与另一个数据框的行的欧氏距离。例如,假设我有以下数据框:
a <- c(1,2,3,4,5)
b <- c(5,4,3,2,1)
c <- c(5,4,1,2,3)
df1 <- data.frame(a,b,c)
a2 <- c(2,7,1,2,3)
b2 <- c(7,6,5,4,3)
c2 <- c(1,2,3,4,5)
df2 <- data.frame(a2,b2,c2)
我想创建一个矩阵,其中包含 df1 中每一行与 df2 中各行的距离。
所以matrix[2,1]应该是df1[2,]和df2[1,]之间的欧氏距离。 matrix[3,2] df[3,]和df2[2,]等的距离
有谁知道这是如何实现的?
也许你可以使用 fields
包:函数 rdist
可能会做你想做的事:
rdist : Euclidean distance matrix
Description: Given two sets of locations computes the Euclidean distance matrix among all pairings.
> rdist(df1, df2)
[,1] [,2] [,3] [,4] [,5]
[1,] 4.582576 6.782330 2.000000 1.732051 2.828427
[2,] 4.242641 5.744563 1.732051 0.000000 1.732051
[3,] 4.123106 5.099020 3.464102 3.316625 4.000000
[4,] 5.477226 5.000000 4.358899 3.464102 3.316625
[5,] 7.000000 5.477226 5.656854 4.358899 3.464102
pdist
包
的情况类似
pdist : Distances between Observations for a Partitioned Matrix
Description: Computes the euclidean distance between rows of a matrix X and rows of another matrix Y.
> pdist(df1, df2)
An object of class "pdist"
Slot "dist":
[1] 4.582576 6.782330 2.000000 1.732051 2.828427 4.242640 5.744563 1.732051
[9] 0.000000 1.732051 4.123106 5.099020 3.464102 3.316625 4.000000 5.477226
[17] 5.000000 4.358899 3.464102 3.316625 7.000000 5.477226 5.656854 4.358899
[25] 3.464102
attr(,"Csingle")
[1] TRUE
Slot "n":
[1] 5
Slot "p":
[1] 5
Slot ".S3Class":
[1] "pdist"
#
注意:如果您正在寻找行之间的欧几里德范数,您可能想尝试:
a <- c(1,2,3,4,5)
b <- c(5,4,3,2,1)
c <- c(5,4,1,2,3)
df1 <- rbind(a, b, c)
a2 <- c(2,7,1,2,3)
b2 <- c(7,6,5,4,3)
c2 <- c(1,2,3,4,5)
df2 <- rbind(a2,b2,c2)
rdist(df1, df2)
这给出:
> rdist(df1, df2)
[,1] [,2] [,3]
[1,] 6.164414 7.745967 0.000000
[2,] 5.099020 4.472136 6.324555
[3,] 4.242641 5.291503 5.656854
改编自。
对于一般的 n
维欧氏距离,我们可以利用方程(不是 R,而是代数):
square_dist(b,a) = sum_i(b[i]*b[i]) + sum_i(a[i]*a[i]) - 2*inner_prod(b,a)
其中总和超过向量 a
和 b
的维度,对于 i=[1,n]
。这里,a
和 b
分别是 df1
和 df2
中的一对列。这里的关键是,这个方程可以写成 df1
和 df2
.
中所有对的矩阵方程
在代码中:
d <- sqrt(matrix(rowSums(expand.grid(rowSums(df1*df1),rowSums(df2*df2))),
nrow=nrow(df1)) -
2. * as.matrix(df1) %*% t(as.matrix(df2)))
备注:
- 内部
rowSums
为 df1
中的每个 a
和 df2
中的每个 b
计算 sum_i(a[i]*a[i])
和 sum_i(b[i]*b[i])
,分别
expand.grid
然后生成 df1
和 df2
之间的所有对。
- 外部
rowSums
计算所有这些对的 sum_i(a[i]*a[i]) + sum_i(b[i]*b[i])
。
- 然后将此结果重塑为
matrix
。注意这个矩阵的行数就是df1
. 的行数
- 然后减去所有对的内积的两倍。这个内积可以写成矩阵乘法
df1 %*% t(df2)
,为了清楚起见,我省略了对矩阵的强制转换。
- 最后,取平方根。
将此代码与您的数据一起使用:
print(d)
## [,1] [,2] [,3] [,4] [,5]
##[1,] 4.582576 6.782330 2.000000 1.732051 2.828427
##[2,] 4.242641 5.744563 1.732051 0.000000 1.732051
##[3,] 4.123106 5.099020 3.464102 3.316625 4.000000
##[4,] 5.477226 5.000000 4.358899 3.464102 3.316625
##[5,] 7.000000 5.477226 5.656854 4.358899 3.464102
请注意,此代码适用于任何 n > 1
。在你的情况下,n=3
.
我想创建一个矩阵,其中包含一个数据框的行与另一个数据框的行的欧氏距离。例如,假设我有以下数据框:
a <- c(1,2,3,4,5)
b <- c(5,4,3,2,1)
c <- c(5,4,1,2,3)
df1 <- data.frame(a,b,c)
a2 <- c(2,7,1,2,3)
b2 <- c(7,6,5,4,3)
c2 <- c(1,2,3,4,5)
df2 <- data.frame(a2,b2,c2)
我想创建一个矩阵,其中包含 df1 中每一行与 df2 中各行的距离。
所以matrix[2,1]应该是df1[2,]和df2[1,]之间的欧氏距离。 matrix[3,2] df[3,]和df2[2,]等的距离
有谁知道这是如何实现的?
也许你可以使用 fields
包:函数 rdist
可能会做你想做的事:
rdist : Euclidean distance matrix
Description: Given two sets of locations computes the Euclidean distance matrix among all pairings.
> rdist(df1, df2)
[,1] [,2] [,3] [,4] [,5]
[1,] 4.582576 6.782330 2.000000 1.732051 2.828427
[2,] 4.242641 5.744563 1.732051 0.000000 1.732051
[3,] 4.123106 5.099020 3.464102 3.316625 4.000000
[4,] 5.477226 5.000000 4.358899 3.464102 3.316625
[5,] 7.000000 5.477226 5.656854 4.358899 3.464102
pdist
包
pdist : Distances between Observations for a Partitioned Matrix
Description: Computes the euclidean distance between rows of a matrix X and rows of another matrix Y.
> pdist(df1, df2)
An object of class "pdist"
Slot "dist":
[1] 4.582576 6.782330 2.000000 1.732051 2.828427 4.242640 5.744563 1.732051
[9] 0.000000 1.732051 4.123106 5.099020 3.464102 3.316625 4.000000 5.477226
[17] 5.000000 4.358899 3.464102 3.316625 7.000000 5.477226 5.656854 4.358899
[25] 3.464102
attr(,"Csingle")
[1] TRUE
Slot "n":
[1] 5
Slot "p":
[1] 5
Slot ".S3Class":
[1] "pdist"
#
注意:如果您正在寻找行之间的欧几里德范数,您可能想尝试:
a <- c(1,2,3,4,5)
b <- c(5,4,3,2,1)
c <- c(5,4,1,2,3)
df1 <- rbind(a, b, c)
a2 <- c(2,7,1,2,3)
b2 <- c(7,6,5,4,3)
c2 <- c(1,2,3,4,5)
df2 <- rbind(a2,b2,c2)
rdist(df1, df2)
这给出:
> rdist(df1, df2)
[,1] [,2] [,3]
[1,] 6.164414 7.745967 0.000000
[2,] 5.099020 4.472136 6.324555
[3,] 4.242641 5.291503 5.656854
改编自
对于一般的 n
维欧氏距离,我们可以利用方程(不是 R,而是代数):
square_dist(b,a) = sum_i(b[i]*b[i]) + sum_i(a[i]*a[i]) - 2*inner_prod(b,a)
其中总和超过向量 a
和 b
的维度,对于 i=[1,n]
。这里,a
和 b
分别是 df1
和 df2
中的一对列。这里的关键是,这个方程可以写成 df1
和 df2
.
在代码中:
d <- sqrt(matrix(rowSums(expand.grid(rowSums(df1*df1),rowSums(df2*df2))),
nrow=nrow(df1)) -
2. * as.matrix(df1) %*% t(as.matrix(df2)))
备注:
- 内部
rowSums
为df1
中的每个a
和df2
中的每个b
计算sum_i(a[i]*a[i])
和sum_i(b[i]*b[i])
,分别 expand.grid
然后生成df1
和df2
之间的所有对。- 外部
rowSums
计算所有这些对的sum_i(a[i]*a[i]) + sum_i(b[i]*b[i])
。 - 然后将此结果重塑为
matrix
。注意这个矩阵的行数就是df1
. 的行数
- 然后减去所有对的内积的两倍。这个内积可以写成矩阵乘法
df1 %*% t(df2)
,为了清楚起见,我省略了对矩阵的强制转换。 - 最后,取平方根。
将此代码与您的数据一起使用:
print(d)
## [,1] [,2] [,3] [,4] [,5]
##[1,] 4.582576 6.782330 2.000000 1.732051 2.828427
##[2,] 4.242641 5.744563 1.732051 0.000000 1.732051
##[3,] 4.123106 5.099020 3.464102 3.316625 4.000000
##[4,] 5.477226 5.000000 4.358899 3.464102 3.316625
##[5,] 7.000000 5.477226 5.656854 4.358899 3.464102
请注意,此代码适用于任何 n > 1
。在你的情况下,n=3
.