【问题标题】:How to improve performance on counting columns in a matrix which are below a threshold?如何提高矩阵中低于阈值的列的计数性能?
【发布时间】:2013-11-20 09:07:18
【问题描述】:

在我的代码中,我从同一矩阵的每一列中减去一个矩阵的一列。 然后我计算有多少新列只有小于r 的元素。 我正在为矩阵的每一列执行此操作。你可以在下面看到我的代码。我省略了将值放入矩阵的部分。

有什么方法可以提高这段代码的性能吗?我似乎无法找到一种方法来加快速度

B = matrix(NA,(m),(window_step))
B_m_r = c(1:(window_step))

for (i in 1:(window_step)){
    B_m_r[i] = sum(apply(abs(B[,-i]-B[,i]), 2,function(x) max(x) < r))
}

解决方案

B = matrix(NA,(m),(window_step))
B_m_r = c(1:(window_step))
buffer_B = matrix(NA,(window_step-1),(window_step-1))

for (i in 1:(window_step-2)){
    buffer_B[i,c(i:(window_step-1))] = apply(abs(B[,-c(1:i)]-B[,i]),2,function(x) max(x) < r)
    B_m_r[i] = (sum(buffer_B[i,c(i:(window_step-1))])+sum(buffer_B[1:i,i]))
}

B_m_r[window_step] = sum(buffer_B[1:(window_step-1),(window_step-1)])
B_m_r[window_step-1] =  sum(buffer_B[1:(window_step-2),(window_step-2)])

好的,根据 Яaffael 的帮助,我找到了一个解决方案,它不会计算两次差异。

相反,我将与矩阵buffer_B 中先前循环的r 比较的结果保存并用于下一个循环以计算小于r 的所有列的总和。

现在代码只需要一半的时间就可以完成。 谢谢!

【问题讨论】:

  • 如何简化代码并删除特殊情况。 f.x.您不能按列减去 A 和 B,因为它们的行数不同(当然,您会以某种方式处理)。这种混乱只会让你和我无法获得清晰的画面。
  • @Яaffael 我将 B 的一列从 B 中的每一列中减去。然后我对 A 做同样的事情。也许这不清楚?我编辑了问题的第一句话以澄清这一点。行数无关紧要,对吧?行数越多,花费的时间就越长,仅此而已。
  • 好吧,很好,但是我的问题是 - 为什么要进行两次相同的计算,而一个足以说明这一点。代码越短,人们花时间思考的机会就越大。我认为也可以删除 window_step 。它可能与您的具体实施有关,但与此问题无关。
  • 是的,你是对的。抱歉,我第一次自己发布了一个问题,而不仅仅是搜索答案;)

标签: r performance matrix


【解决方案1】:

您可以例如通过仅检查一半列差异的“

您正在计算 abs(first of B - last of B) 和 abs(last of B - first of B)。

PLUS您可以预先计算处理后的差异矩阵,而不是使用 for 循环来逐步设置它。

# I am using single-row matrices to keep it simple

> A <- matrix(1:4,ncol=4)

> A[,1:ceiling(ncol(A)/2)]
[1] 1 2

> A[,ncol(A):(floor(ncol(A)/2)+1)]
[1] 4 3

> A <- matrix(1:5,ncol=5)

> A[,1:ceiling(ncol(A)/2)]
[1] 1 2 3

> A[,ncol(A):(floor(ncol(A)/2)+1)]
[1] 5 4 3

> abs(A[,1:ceiling(ncol(A)/2)] - A[,ncol(A):(floor(ncol(A)/2)+1)])
[1] 4 2 0

当您想加速 R 中的代码时,您首先应该尝试使用 R 函数将所有循环转换为向量化表达式。循环将在 R 中运行。向量化的函数调用允许 R 执行实质上已编译的 C 代码。

【讨论】:

  • 是的,我正在检查所有内容两次。然后我的解决方案是用abs(B[,-c(1:i)]-B[,i]) 替换abs(B[,-i]-B[,i])。但我需要每个原始列的“abs”列数小于r
  • 例如。对于 i=1,我检查 (B[,2]-B[,1])、(B[,3]-B[,1]) 等等。但是对于 i = 2,我不会检查 (B[,1]-B[,2]) 但我需要知道 B_m_r[2] 中的总和是否小于或大于 r
  • 我需要为每个循环周期预先计算一个差分矩阵,因为在每个 for 循环中,我从 每个 其他列中减去一列以创建差分矩阵。 abs(B[,-i] - B[,i]) 创建一个完整的矩阵,其中除 B[,i] 之外的 B 的每一列都减去 B[,i] 列。
猜你喜欢
  • 1970-01-01
  • 2022-12-11
  • 1970-01-01
  • 1970-01-01
  • 2022-11-03
  • 2019-08-01
  • 2019-11-13
  • 1970-01-01
  • 2017-07-05
相关资源
最近更新 更多