【问题标题】:Why does this vectorized matrix comparison fail?为什么这个向量化矩阵比较会失败?
【发布时间】:2013-12-30 22:15:50
【问题描述】:

我正在尝试将矩阵的第一行与同一矩阵的所有行进行比较。但是矢量化比较没有返回正确的结果。为什么会发生这种情况?

m <- matrix(c(1,2,3,1,2,4), nrow=2, ncol=3, byrow=TRUE)

> m
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    1    2    4

> # Why does the first row not have 3 TRUE values?
> m[1,] == m
      [,1]  [,2]  [,3]
[1,]  TRUE FALSE FALSE
[2,] FALSE FALSE FALSE

> m[1,] == m[1,]
[1] TRUE TRUE TRUE

> m[1,] == m[2,]
[1]  TRUE  TRUE FALSE

跟进。在我的实际数据中,我有大量的行(至少 1000 万行),然后时间和内存都加起来了。其他人在下面提出的其他建议?

m <- matrix(rep(c(1,2,3), 1000000), ncol=3, byrow=TRUE)

> #by @alexis_laz
> m1 <- matrix(m[1,], nrow = nrow(m), ncol = ncol(m), byrow = T)
> system.time(m == m1)
   user  system elapsed 
   0.21    0.03    0.31

> object.size(m1)
24000112 bytes

> #by @PaulHiemstra
> system.time( t(apply(m, 1, function(x) x == m[1,])) )
   user  system elapsed 
  35.18    0.08   36.04 

跟进 2。 @alexis_laz 你是对的。我想比较每一行,并发布了一个后续问题 (How to vectorize comparing each row of matrix with all other rows)

【问题讨论】:

  • 您也可以将m[1,] 转换为矩阵并进行比较:m == matrix(m[1,], nrow = nrow(m), ncol = ncol(m), byrow = T)
  • 后续跟进,您的最终目标是什么?例如。您想针对矩阵的其余部分测试每一行是否相等?您想针对每个矩阵的其余部分测试许多矩阵的第一行吗?或者您只是想尽快测试单个矩阵的第一行与其余部分的对比?

标签: r matrix comparison vectorization


【解决方案1】:

在比较m[1,] == m 中,第一项m[1,] 被回收(一次)以等于m 的长度。然后按列进行比较。

您将c(1,2,3)c(1,1,2,2,3,4) 进行比较,因此c(1,2,3,1,2,3)c(1,1,2,2,3,3,4) 进行比较,因此您有一个TRUE,后跟五个FALSE(并打包为矩阵以匹配m 的尺寸)。

【讨论】:

    【解决方案2】:

    正如@MatthewLundberg 所指出的,R 的回收规则并不像您预期​​的那样运行。在我看来,最好明确说明要比较的内容,而不是依赖 R 的假设。进行正确比较的一种方法:

    t(apply(m, 1, function(x) x == m[1,]))
         [,1] [,2]  [,3]
    [1,] TRUE TRUE  TRUE
    [2,] TRUE TRUE FALSE
    

    或:

    m == rbind(m[1,], m[1,])
         [,1] [,2]  [,3]
    [1,] TRUE TRUE  TRUE
    [2,] TRUE TRUE FALSE
    

    或者让 R 的回收工作对你有利(感谢 @Arun):

    t(t(m) == m[1,])
         [,1] [,2]  [,3]
    [1,] TRUE TRUE  TRUE
    [2,] TRUE TRUE FALSE
    

    【讨论】:

    • 这个问题,不仅仅是回收,是由于按列比较,不是吗?
    • @Arun 你是对的,正如马修已经回答的那样。我只是提供了一个解决方案,其中两个不依赖于 R 的回收规则。
    • +1,很高兴您也提供了解决方案。对于第二种情况,也可以这样做:m == m[c(1L,1L), ].
    • 我的矩阵中实际上有 1e+06 行,所以我的目标是矢量化。其他建议? m &lt;- matrix(rep(c(1,2,3), 1000000), ncol=3, byrow=TRUE) system.time( t(apply(m, 1, function(x) x == m[1,])) ) user system elapsed 37.07 1.06 40.63
    • 试试@Arun 的解决方案,应该会更快,但会消耗内存。
    猜你喜欢
    • 2012-04-17
    • 2019-10-23
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多