【问题标题】:efficiently update matrix element with a matrix of indices使用索引矩阵有效地更新矩阵元素
【发布时间】:2012-11-08 20:14:00
【问题描述】:

我有一个索引矩阵 I,其中一些索引重复。下面我举个例子。

我有另一个矩阵 A,其尺寸与索引兼容,并且在任何地方都初始化为 0。我想做类似的事情

A[I] += 1

我面临两个问题:

  1. A[I] = A[I] + 1效率太低了
  2. 矩阵I 有冗余索引。例如第 2 行和第 6 行是相同的,我想获得 A[1,2] = 2

部分答案是创建一个 3 列矩阵,其中前两列是 unique(I) 的乘积,第三列是计数的乘积,但我也没有看到任何解决方案。任何指针或帮助将不胜感激!

> I is:
     [,1] [,2]
[1,]    1    1
[2,]    1    2
[3,]    1    3
[4,]    1    4
[5,]    1    1
[6,]    1    2
[7,]    1    3

【问题讨论】:

  • “索引”一词指的是一个位置。您将其与该位置的值混淆了。如果I 是一个矩阵,那么A[I] 极不可能按照您的想法去做。请提供A 的小样本以及您希望更新后的A 矩阵的样子。
  • 下面的答案很好。我想知道你的“效率太低”的说法。 AI 有多大...?
  • @BenBolker: 2.5e+09 矩阵单元是我开始处理的,它可以更大,因为我在文本挖掘中编写文档术语矩阵,其中每一行都是一个文档,每列是整个词汇表中的一个词。

标签: r matrix


【解决方案1】:

这可能是使用稀疏矩阵方法最快的方法(参见 Matrix 包和其他方法)。

使用标准矩阵,您可以使用 xtabs 函数折叠相同的行,然后使用矩阵分配(根据评论进行编辑):

I <- cbind(1, c(1:4,1:3))

tmp <- as.data.frame(xtabs( ~I[,1]+I[,2] ))

A <- matrix(0, nrow=5, ncol=5)
tmp2 <- as.matrix(tmp[,1:2])
tmp3 <- as.numeric(tmp2)
dim(tmp3) <- dim(tmp2)
A[ tmp3 ] <- tmp[,3]
A

您可以通过将核心功能从as.data.frame.table 中提取出来而不是转换为数据框并再次返回来加快速度。

这是另一个可能更有效的版本。它会用xtabs计算的其他0覆盖一些0:

I <- cbind(1:5,1:5)
A <- matrix(0, 5, 5)

tmp <- xtabs( ~I[,2]+I[,1] )

A[ as.numeric(rownames(tmp)), as.numeric(colnames(tmp)) ] <- c(tmp)
A

如果 A 矩阵有 dimnames 并且 I 矩阵有名称而不是索引,那么后面的也可以工作(只需删除 as.numerics。

【讨论】:

  • 我喜欢使用xtabs() 的想法,但这并没有达到预期的目的。 (看看A 看看)。问题是对as.numeric() 的调用将字符matrix 转换为数字vector,这完全改变了索引的含义。
  • @JoshO'Brien,你能详细说明一下吗?我的 A 矩阵符合我的预期。有什么区别?
  • 当然。例如,用I &lt;- cbind(1:5, 1:5) 试试你的,看看有没有问题。然后查看as.numeric(as.matrix(tmp[,1:2])) 的值以了解原因。 (我假设你和我都同意将 I &lt;- cbind(1:5, 1:5) 输入你的代码的结果应该是 5×5 单位矩阵。)
  • @JoshO'Brien,好的,我看到问题(没有仔细阅读您的评论)是矩阵的维度被删除了。我将用更好的解决方案编辑上面的代码。
【解决方案2】:

给你:

## Reproducible versions of your A and I objects
A <- matrix(0, nrow=2, ncol=5)
## For computations that follow, you'll be better off having this as a data.frame
## (Just use `I <- as.data.frame(I)` to convert a matrix object I).
I <- read.table(text=" 1    1
1    2
1    3
1    4
1    1
1    2
1    3", header=FALSE)

## Create data.frame with number of times each matrix element should
## be incremented
I$count <- ave(I[,1], I[,1], I[,2], FUN=length)
I <- unique(I)

## Replace desired elements, using a two column matrix (the "third form of
## indexing" mentioned in "Matrices and arrays" section" of ?"[").
A[as.matrix(I[1:2])] <- I[[3]]

A
#      [,1] [,2] [,3] [,4] [,5]
# [1,]    2    2    2    1    0
# [2,]    0    0    0    0    0

【讨论】:

    猜你喜欢
    • 2015-12-09
    • 1970-01-01
    • 2016-02-05
    • 1970-01-01
    • 1970-01-01
    • 2014-03-13
    • 1970-01-01
    • 1970-01-01
    • 2011-05-27
    相关资源
    最近更新 更多