快速总结一份清单?

时间:2016-05-23 21:25:11

标签: r

我有10000个列表(模拟结果),每个列表包含22500个列表(每个列表是图像中的一个像素),其中包含一个长度为55的向量。

# Simple Example
m <- replicate(2, list(runif(55))) 
m2 <- replicate(3, list(m)) 
str(m2,list.len = 3)

List of 3
 $ :List of 4
  ..$ : num [1:55] 0.107 0.715 0.826 0.582 0.604 ...
  ..$ : num [1:55] 0.949 0.389 0.645 0.331 0.698 ...
  ..$ : num [1:55] 0.138 0.207 0.32 0.442 0.721 ...
  .. [list output truncated]
 $ :List of 4
  ..$ : num [1:55] 0.107 0.715 0.826 0.582 0.604 ...
  ..$ : num [1:55] 0.949 0.389 0.645 0.331 0.698 ...
  ..$ : num [1:55] 0.138 0.207 0.32 0.442 0.721 ...
  .. [list output truncated]
 $ :List of 4
  ..$ : num [1:55] 0.107 0.715 0.826 0.582 0.604 ...
  ..$ : num [1:55] 0.949 0.389 0.645 0.331 0.698 ...
  ..$ : num [1:55] 0.138 0.207 0.32 0.442 0.721 ...
  .. [list output truncated]

# my function
m3 <- lapply(seq_along(m2[[1]]), FUN = function(j) Reduce('+', lapply(seq_along(m2), FUN = function(i) m2[[i]][[j]])))
#by hand
identical(m2[[1]][[1]] + m2[[2]][[1]] + m2[[3]][[1]], m3[[1]] )

我用Reduce编写了一个嵌套的lapply来对列表求和。在一个小例子中,如上所述,它很快,但根据我的真实数据,它真的很慢。

#slow code
m <- replicate(22500, list(runif(55))) 
m2 <- replicate(10000, list(m)) 
str(m2,list.len = 3)
m3 <- lapply(seq_along(m2[[1]]), FUN = function(j) Reduce('+', lapply(seq_along(m2), FUN = function(i) m2[[i]][[j]])))

如何加快速度,或者我应该更改数据结构?

感谢。

1 个答案:

答案 0 :(得分:4)

这提供了一些改进(> 2x):

split(Reduce(`+`, lapply(m2, unlist)), rep(seq_along(m2[[1]]), lengths(m2[[1]])))

由于您的数据基本上是矩形的,您是否已将其存储为此形状:

library(data.table)
d = rbindlist(lapply(m2, function(x) transpose(as.data.table(x))), id = T
             )[, id.in := 1:.N, by = .id]
#   .id        V1         V2           V55 id.in
#1:   1 0.4605065 0.09744975 ... 0.8620728     1
#2:   1 0.6666742 0.10435471 ... 0.3991940     2
#3:   2 0.4605065 0.09744975 ... 0.8620728     1
#4:   2 0.6666742 0.10435471 ... 0.3991940     2
#5:   3 0.4605065 0.09744975 ... 0.8620728     1
#6:   3 0.6666742 0.10435471 ... 0.3991940     2

您可以通过以下方式更快地进行聚合:

d[, lapply(.SD, sum), by = id.in]

但如果列表是您的起点,转换将占用大部分时间。