r - 将矩阵转换为三元组 (i,j,v) 的有效方法
问题描述
什么
鉴于一些matrix
:
mat <- matrix(1:10,ncol=2)
我想将其转换为以下三元组格式: (i,j,v) 其中i
是行索引,j
是列索引,是 i,j 处的值(您可以在底部v
看到原因)
我试过的:
matrixToTriplet <- function(mat) {
i <- 1:nrow(mat)
nj <- ncol(mat)
j <- 1:nj
output <- matrix(numeric(0), ncol=3)
for(i_ in i) {
curr <- c(rep(i_, times=nj),j,mat[i_,])
output <- rbind(output, matrix(curr, ncol=3))
}
output
}
输出应该是:
> matrixToTriplet(mat)
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 2 6
[3,] 2 1 2
[4,] 2 2 7
[5,] 3 1 3
[6,] 3 2 8
[7,] 4 1 4
[8,] 4 2 9
[9,] 5 1 5
[10,] 5 2 10
我还有另一个版本使用apply
andsapply
而不是,for
但那些会很快爆炸。我正在处理的尺寸非常大,1600x1600 矩阵。
为什么
有人可能会问“为什么”?原因是我需要i
s 和j
s 作为模型预测的特征v
。如果有更好的方法来做到这一点,我很想听听。
解决方案
你可以用row
and做到这一点col
:
x <- t(mat)
cbind(c(col(x)), c(row(x)), c(x))
# [,1] [,2] [,3]
# [1,] 1 1 1
# [2,] 1 2 6
# [3,] 2 1 2
# [4,] 2 2 7
# [5,] 3 1 3
# [6,] 3 2 8
# [7,] 4 1 4
# [8,] 4 2 9
# [9,] 5 1 5
# [10,] 5 2 10
如果最终输出中的行顺序无关紧要,我们也可以cbind(c(row(mat)), c(col(mat)), c(mat))
直接使用。
在谈论效率时,基准会有所帮助:
library(microbenchmark)
bmf <- function(mat, ...){
microbenchmark(
a = {x <- t(mat);cbind(c(col(x)), c(row(x)), c(x))},
a2 = {cbind(c(row(mat)), c(col(mat)), c(mat))},
b = {cbind(which(mat > 0, arr.ind = TRUE), val = c(mat))},
c = {cbind(expand.grid(seq(nrow(mat)), seq(ncol(mat))), as.vector(mat))},
...)
}
mat <- matrix(seq_len(10*10), 10, 10)
bmf(mat, times = 10)
# Unit: microseconds
# expr min lq mean median uq max neval
# a 7.985 9.239 18.2556 15.0415 22.756 47.065 10
# a2 4.310 4.681 5.5257 5.2405 5.755 9.099 10
# b 17.032 21.672 35.8950 28.7505 59.170 68.436 10
# c 216.101 228.736 267.7217 243.9465 288.455 380.096 10'
mat <- matrix(seq_len(1000*1000), 1000, 1000)
bmf(mat, times = 10)
# Unit: milliseconds
# expr min lq mean median uq max neval
# a 17.70805 20.51167 36.73432 21.79357 24.56775 111.6796 10
# a2 14.61793 20.95486 37.70526 25.58968 30.91322 98.44344 10
# b 41.74630 45.49698 76.61307 47.86678 122.90142 178.8363 10
# c 14.40912 17.84025 25.39672 19.29968 20.12222 85.2515 10
推荐阅读
- python - Paho MQTT:未发送消息队列并重新启动
- java - 有没有一种简单的方法来反转经历溢出的整数函数?
- reactjs - React Hooks - 将进程仅传递一次道具的逻辑放在哪里?
- javascript - 使用 html CSS 和 javascript 创建轮播的问题
- xml - 如何将带有位置的 XML 文件集成到 ReactJS 谷歌地图中?
- c# - 玩家生命每帧而不是每秒增加
- flutter - 不推荐使用 BitmapDescriptor.fromAsset
- javascript - 用于匹配 YouTube 嵌入 ID 的正则表达式
- asp.net-mvc - 在 .NET MVC 中 - 我们如何取回键/名称值的参数映射
- vue.js - 允许在 VueJs 中使用可扩展的应用程序架构