仅熔化矩阵中的最高值

Posted

技术标签:

【中文标题】仅熔化矩阵中的最高值【英文标题】:Melt only highest values in matrix 【发布时间】:2017-12-26 19:57:22 【问题描述】:

我有一个大型方阵,其中包含每行或每列之间的相关性:

mat <- matrix(rnorm(5000 * 5000), nrow = 5000, dimnames = list(
    paste0("ID", seq_len(5000)), paste0("ID", seq_len(5000))))

我想从这个矩阵中提取前 100,000 个唯一对(即 ID1-ID2 与 ID2-ID1 相同),然后将它们转换为数据框。目前,我正在使用此代码:

corDat <- reshape2::melt(mat, varnames = c("id.A", "id.B"),
                       value.name = "value", na.rm = T)
corDat <- corDat[as.character(corDat$id.A) < as.character(corDat$id.B),]
corDat <- corDat[order(-corDat$value),]
top_n <- 100000
corDat <- corDat[seq_len(top_n),]

结果:

head(corDat)

           id.A   id.B    value
19316931 ID1931 ID3864 5.658092
14312231 ID2231 ID2863 5.416562
3225529   ID529  ID646 5.357433
3492653  ID2653  ID699 5.297154
17046659 ID1659 ID3410 5.105343
3323364  ID3364  ID665 4.987266    
...

但是,由于矩阵很大,上面的前两个操作(melt矩阵和删除重复对)需要很长时间,通常超过 5 分钟。我需要将此操作应用于数百个可变大小的方阵(通常大于 5000x5000)。

我确信必须有一种更快的方法来提取这些信息,因为我实际上不需要融合整个矩阵——只需要与前 100,000 个值关联的行和列名。如何更有效地完成此操作?

【问题讨论】:

当你说“top 100,000 unique pairs”时,你是指矩阵mat的上三角吗? 【参考方案1】:

这是使用索引的基本 R 版本:

up <- upper.tri(mat)
inds <- which( up , arr.ind = TRUE )
out <- data.frame( id.A = rownames(mat)[ inds[,1] ] , id.B = rownames(mat)[ inds[,2] ] , value = mat[up] )
#order and select the top ten:
out[order(-out$value),][1:10,]

在我的机器上,这比 melt 快大约 3.5 倍。

我假设您想要矩阵的上三角部分。

请注意,您的 as.character(corDat$id.A) &lt; as.character(corDat$id.B) 语句不会选择上三角部分,因为多位字符串比较的工作方式(例如,"ID10" &lt; "ID7" 的计算结果为 TRUE)。

【讨论】:

感谢您澄清关于 R 中字符串比较的这一点,我不知道这一点。是的,我所说的唯一对仅指矩阵的上(或下)三角形——实际上矩阵是对称的,尽管在我的示例中我并没有考虑让它对称。

以上是关于仅熔化矩阵中的最高值的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Matlab 中的 .mat 文件中仅加载一个单元格的条目?

如何查询仅出现特定列中具有最高值的行的行?

是否可以仅为测试数据计算特征矩阵?

使用 Power Query,应用筛选器以仅显示最高值

通过 Matlab 中的移动索引移动矩阵中的批量行

R中的性能:对矩阵中的行元素进行排序的最快方法是啥?