我有一个长向量 x 和另一个包含长度的 v。我想对 x 求和,以便答案 y
是长度为 length(v)
的向量,而 y[1]
是 sum(x[1:v[i]])
, y[2]
是 sum(x[(1+v[1]):(v[1 ]+v[2])])
,等等。本质上,这是从length(x)
维度空间到一维length(v)
维度执行稀疏矩阵乘法。然而,我宁愿不引进“先进机械”,尽管我可能不得不这样做。它确实需要非常非常快。有人能想到比使用稀疏矩阵包更简单的方法吗?
示例 -
x <- c(1,1,3,4,5)
v <- c(2,3)
y <- myFunc(x,v)
y
应该是 c(2,12)
我对任何预处理持开放态度 - 例如,将每个拉伸(stretch)的起始索引存储在 v 中。
最佳答案
y <- cumsum(x)[cumsum(v)]
y <- c(y[1], diff(y))
这看起来像是做了额外的工作,因为它正在计算整个向量的累积和,但实际上,无论对于少量还是大量的组,它都比迄今为止的其他解决方案更快。
这是我模拟数据的方式
set.seed(5)
N <- 1e6
n <- 10
x <- round(runif(N,0,100),1)
v <- as.vector(table(sample(n, N, replace=TRUE)))
在我的机器上,计时为 n <- 10
是:
- 布兰登·贝特尔森(for 循环):0.017
- Ramnath(行总和):0.057
- 约翰(分割/应用):0.280
- 亚伦(累积值):0.008
更改为n <- 1e5
时间安排是:
- 布兰登·贝特尔森(for 循环):2.181
- Ramnath(行总和):0.226
- 约翰(分割/应用):0.852
- 亚伦(累计):0.015
我怀疑这比矩阵乘法更快,即使使用稀疏矩阵包也是如此,因为不需要形成矩阵或进行任何乘法。如果需要更快的速度,我怀疑可以通过用 C 语言编写来加快速度;不难做到inline
和rcpp
包,但我会把它留给你。
关于r - 使用 R 计算拉伸(stretch)向量的滚动和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7974300/