我正在寻找一种方法来水平移动方阵的行。特别是,我的问题是针对矩阵维度非常大的情况,比如 500*500 或 1000*1000,但我在这里举了一个 5*5 的小例子来说明这一点。假设我们有以下矩阵:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
Run Code Online (Sandbox Code Playgroud)
我想水平移动我得到以下矩阵的行并用零填充空单元格:
1 7 13 19 25
2 8 14 20 0
3 9 15 0 0
4 10 0 0 0
5 0 0 0 0
Run Code Online (Sandbox Code Playgroud)
为像这样的小矩阵编写代码很容易R,但我正在寻找非常大的矩阵,正如我在上面指出的那样。任何帮助,将不胜感激。
该示例建议您创建一个新矩阵,其第 j列是原始矩阵的第j行,向左移动 j-1 个位置并在右侧填充零,如在此计算中使用 10,000 X 10,000 矩阵:
n <- 1e4
a <- matrix(seq_len(n^2), n, byrow=TRUE)
system.time({
b <- matrix(sapply(seq_len(nrow(a)), function(i) c(a[i,i:ncol(a)], rep(0, i-1))), n, n)
})
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)user system elapsed 0.97 0.00 0.99
(这是使用单个线程并反映了许多测试运行的典型运行。)对于具有 100,000,000 个条目的矩阵来说,一秒钟也不错。不过,这是一个很大的 RAM 猪,因此如果输入是稀疏矩阵,您可能需要修改代码,以便它也输出稀疏矩阵。
考虑到这一点,我c突然想到,假设可以极快地初始化零矩阵,那么避免串联并仅就地复制应该会更快。事实证明确实如此(而且代码更简单):
system.time({
b <- matrix(0, nrow(a), ncol(a))
for (i in seq_len(nrow(a))) b[1:(n+1-i), i] <- a[i, i:ncol(a)]
})
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)user system elapsed 0.62 0.00 0.62
它快了大约 50%。由于循环开销相对较小并且循环体(大概)是优化的向量副本,因此不太可能存在明显更快的单线程解决方案。
| 归档时间: |
|
| 查看次数: |
103 次 |
| 最近记录: |