首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何根据R中稀疏矩阵的阈值替换行值?

如何根据R中稀疏矩阵的阈值替换行值?
EN

Stack Overflow用户
提问于 2020-06-04 03:20:18
回答 2查看 687关注 0票数 0

我有一个很大的稀疏矩阵(40,000 x 100,000+),如果它大于某个阈值,我想将它替换为1。但是,矩阵中的每一行都有一个唯一的阈值(这只是一个向量,即行的长度),因此我想逐行检查特定行的元素是否大于该行的唯一阈值。

我最初通过遍历稀疏矩阵的所有非零元素来尝试使用for循环来解决这个问题,但是这花费了很长时间,因为我有超过1亿多个元素要通过。

代码语言:javascript
运行
复制
number_of_elem <- matrix@x %>% length()
for (j in 1:number_of_elem){

  threshold <- thres_array[j] 

  if (threshold == 0){
    next
  }

  if (matrix@x[j] > threshold){

    matrix@x[j] <- 1

  }

}

然后,我开始尝试使用apply函数,但是,如果阈值为零,我无法准确地解决跳过阈值的问题。作为参考,我首先计算了每一行的分位数,并将阈值设置为高于第95百分位数。由于它是一个稀疏矩阵,一些阈值值为零。

对如何处理这件事有什么想法吗?据我所知,在R中,非常倾向于将代码向量化并避免for循环,但我想不出一种可持续的方法。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-06-04 16:31:34

我修改了@Bas解决方案,使其能够利用矩阵的稀疏性,从而提高性能。

代码语言:javascript
运行
复制
mat@x[mat@x > thres_array[mat@i + 1] ] <- 1

mat@x给出稀疏矩阵的非零元素,mat@i给出非零元素所属的行(您必须添加1,因为它是零索引的)。由于thres_array的元素基于相应的行,所以可以从mat@x > thres_array[mat@i + 1]生成一个逻辑向量,并将这些值重新分配到1。

票数 1
EN

Stack Overflow用户

发布于 2020-06-04 07:03:51

您说得对,在R中,通常倾向于将代码向量化。幸运的是,如果我正确理解了你的问题,在这种情况下,这是很容易做到的。

由于您没有提供任何数据(请在将来这样做),我在下面生成了一个阈值数组thres_array和一个矩阵mat

然后,将thres_array的每个条目与整个mat行进行比较是一个mat > thres_array问题,应用阈值也可以在一行中完成。

通过在thres_array witn Inf中替换零,我们确保mat > thres_array永远不会为真,从而跳过这些值。

代码语言:javascript
运行
复制
thres_array <- 0:9
mat <- matrix(runif(1000, max = 10), nrow = 10)

# get rid of zeros
thres_array[thres_array == 0] <- Inf

# apply threshold
mat[mat > thres_array] <- 1

对于我随机生成的矩阵mat,如下所示。

代码语言:javascript
运行
复制
           [,1]     [,2]      [,3]      [,4]     [,5]      [,6]     [,7]       [,8]     [,9]     [,10]    [,11]    [,12]     [,13]    [,14]
 [1,] 8.80034895 8.422070 4.9415068 5.0451436 2.038524 0.1091817 7.900194 4.22983010 1.318235 3.9218194 7.491424 1.414268 8.9569142 3.347458
 [2,] 1.00000000 1.000000 1.0000000 1.0000000 0.654243 1.0000000 1.000000 1.00000000 1.000000 1.0000000 1.000000 1.000000 1.0000000 1.000000
 [3,] 1.00000000 1.000000 1.2302859 1.0000000 1.000000 0.9299740 1.000000 1.00000000 1.661907 1.0000000 1.000000 1.293784 1.0000000 1.987043
 [4,] 1.01573038 1.566547 1.0000000 1.0000000 2.469330 1.0000000 0.609428 2.04922439 1.000000 1.0000000 1.000000 1.000000 1.0000000 1.000000
 [5,] 1.00000000 1.000000 0.2595911 1.0000000 1.000000 3.0623223 1.000000 1.00000000 3.333816 0.7444644 1.000000 1.253450 2.6955623 1.000000
 [6,] 3.66609571 1.000000 2.0263511 2.5939923 1.000000 1.0000000 1.536697 0.41910933 3.586519 1.0000000 1.000000 4.921295 1.7967002 1.000000
 [7,] 1.00000000 1.000000 ...
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62186299

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档