r - 在两个矩阵的所有行对上使用函数
问题描述
如果我想计算两个向量的 n 维距离,我可以使用如下函数:
a = c(1:10)
b = seq(20, 23, length.out = length(a))
test_fun =
function(x,y) {
return(
sqrt(
sum(
(x - y) ^ 2
)
)
)
}
n_distance = test_fun(a,b)
现在,我想将其扩展为矩阵设置:我想计算两个矩阵的每对行的 n 维距离。
set.seed(123)
a_mtx = matrix(1:30, ncol = 5)
b_mtx = matrix(sample(1:15,15), ncol = 5)
n_distance_mtx =
matrix(
NA,
nrow = nrow(b_mtx),
ncol = nrow(a_mtx)
)
for(i in 1:nrow(b_mtx)) {
for(j in 1:nrow(a_mtx)) {
n_distance_mtx[i,j] =
test_fun(a_mtx[j,], b_mtx[i,])
}
}
其中 的每一列n_distance_mtx
包含 和 的每一行之间的距离度量(a_mtx
和之间的距离也是b_mtx
如此。n_distance_mtx[,1]
a_mtx[1,]
b_mtx[1:3,]
如果我计算列的平均值,n_distance_mtx
我可以获得 中的每一行a_mtx
与 的所有行之间的平均距离b_mtx
。
colMeans(n_distance_mtx)
#[1] 23.79094 24.90281 26.15618 27.53303 29.01668 30.59220
所以23.79094是 和 之间的平均距离a_mtx[1,]
,b_mtx[1:3,]
而24.90281a_mtx[2,]
是和之间的平均距离b_mtx[1:3,]
,依此类推。
问题:如何在不使用 for 循环的情况下获得相同的解决方案?
我想将此方法应用于具有更大维度的矩阵(大约数十万行)。看着this和this,似乎必须有一种方法可以用Vectorize
douter
函数来完成这个,但我一直无法生成这样的函数。
test_fun_vec =
Vectorize(
function(x,y) {
outer(
x,
y,
test_fun
)
}
)
test_fun_vec(a_mtx,b_mtx)
#[1] 4 0 2 7 4 6 3 5 1 5 7 5 10 0 9 11 15 17 8 11 9 12 10 16
#[25] 10 22 20 25 15 24
解决方案
我们可以Vectorize
使用outer
f1 <- Vectorize(function(i, j) test_fun(a_mtx[j, ], b_mtx[i, ]))
out <- outer(seq_len(nrow(b_mtx)), seq_len(nrow(a_mtx)), FUN = f1)
out
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 20.88061 21.84033 22.97825 24.26932 25.69047 27.22132
#[2,] 24.87971 25.57342 26.43861 27.45906 28.61818 29.89983
#[3,] 25.61250 27.29469 29.05168 30.87070 32.74141 34.65545
colMeans(out)
#[1] 23.79094 24.90281 26.15618 27.53303 29.01668 30.59220
identical(n_distance_mtx, out)
#[1] TRUE
推荐阅读
- reporting-services - 带有渐进式搜索的 SSRS 下拉菜单
- c - 将局部变量设置为全局,以便主函数可以在 C 中访问它
- python - 如何在 python 中实际使用 NotImplementedError?
- c++ - 使用强类型定义 CPP 定义枚举
- mysql - 如何从查询mysql中的选定列中选择记录
- php - 如何在单个屏幕中按类别和子类别显示所有产品?
- java - spring LDAP 不会抛出特定的错误代码
- javascript - 使用国家代码 +39 06 时 google-libphonenumber 的问题
- python - 我正在尝试在 Python 中使用 Matplotlib 执行代码,并在将 fill_between() 用于 matplotlib 3.3.0 时遇到以下问题
- java - 如何将 Build>Project 绑定到 Javatar(Sublime Text 3)中的键?