使用apply从矩阵构建特征张量

时间:2018-07-27 11:15:31

标签: arrays r embedding tensor

考虑以下代码:

EmbedFeatures <- function(x,w) {
     c_rev <- seq(from=w,to=1,by=-1)
     em <- embed(x,w)
     em <- em[,c_rev]
     return(em)
}

m=matrix(1:1400,100,14)

X.tr<-c()
F<-dim(m)[2]
W=16
for(i in 1:F){ X.tr<-abind(list(X.tr,EmbedFeatures(m[,i],W)),along=3)}

这将构建一系列功能,每行具有W = 16个时间步长。 尺寸为:

> dim(X.tr)
[1] 85 16 14

以下是第一个示例:

> X.tr[1,,1]
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16
> X.tr[1,,2]
 [1] 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
> X.tr[1,,3]
 [1] 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216

我想使用apply来构建这个数组,但是以下代码不起作用:

X.tr <- apply(m,2,EmbedFeatures, w=W)

因为它具有以下尺寸:

> dim(X.tr)
[1] 1360   14

我该怎么办?

1 个答案:

答案 0 :(得分:1)

首先,感谢您提供了一个很好的可复制示例!

现在,据我所知,您无法使用apply执行此操作。但是,可以结合使用plyr::aaplybase::aperm来完成多维数组的转换,aaply可以返回多维数组。

有关aperm功能的详细信息,请参见here;有关library(plyr) Y.tr <- plyr::aaply(m, 2, EmbedFeatures, w=W) Z.tr <- aperm(Y.tr, c(2,3,1)) dim(Y.tr) [1] 14 85 16 dim(Z.tr) [1] 85 16 14 功能的详细信息,请参见here

在上面运行代码后,您可以执行以下操作:

using_aaply <- function(m = m) {
    Y.tr <- aaply(m, 2, EmbedFeatures, w=W)
    Z.tr <- aperm(Y.tr, c(2,3,1))
    return(Z.tr)
}

我把这两行代码变成了一个函数。

library(microbenchmark)
microbenchmark(for(i in 1:F){ X.tr<-abind(list(X.tr,EmbedFeatures(m[,i],W)),along=3)}, times=100)

Unit: milliseconds
                                                                                  expr
 for (i in 1:F) {     X.tr <- abind(list(X.tr, EmbedFeatures(m[, i], W)), along = 3) }
      min       lq     mean   median       uq      max neval
 405.0095 574.9824 706.0845 684.8531 802.4413 1189.845   100

microbenchmark(using_aaply(m=m), times=100)

Unit: milliseconds
               expr      min       lq     mean   median       uq      max
 using_aaply(m = m) 4.873627 5.670474 7.797129 7.083925 9.674041 19.74449
 neval
   100

然后我做了一些微基准测试。

aaply

与for循环中的aperm相比,使用abindconst file = storage .bucket('example_bucket') .file('examplefile.mp4'); file.download({destination: 'test.mp4'}, (err) => { let command = ffmpeg() .input('test.mp4') .duration(10) .format('mp4'); command.save('test_out.mp4'); }); res.json([{ message: 'Command sent!' }]); 加载似乎更快。