【问题标题】:Vectorizing a matrix [duplicate]向量化矩阵[重复]
【发布时间】:2011-06-02 00:22:27
【问题描述】:

我有一个 1000 x 1000 的大型 2D 矩阵。我想重新调整它的形状,使其成为一列(或一行)。例如,如果矩阵是:

A B C
1 4 7
2 5 8
3 6 9

我想把它变成:

1 2 3 4 5 6 7 8 9

我不需要保留列标题,只需保留数据的顺序。我如何使用reshape2(我认为这是最容易使用的软件包)来做到这一点?


为了澄清,我提到了reshape,因为我认为这是最好的方法。我可以看到有一些我非常满意的更简单的方法。

【问题讨论】:

  • 无论何时对矩阵进行矢量化处理,请记住它总是排在前面。当您需要保留行顺序时,请执行c(t(some.matrix))
  • 更改了标题以反映所提出的问题。顺便说一句,我想知道那种重塑恋物癖是从哪里来的。我看到有很多问题要求对一个从一开始就没有构建 reshape 的问题进行 reshape 答案。
  • @Joris 也许“如果你只有一把锤子,那么一切看起来都像钉子。”?
  • @Joris - 真的是无知。我只是假设我想做的不是标准操作。我使用 ggplot2,其中有时会提到 reshape2,因为它们都是由 Hadley Wickham 制作的。

标签: r vector statistics matrix


【解决方案1】:

我认为很难找到比以下更紧凑的方法:

c(m)
[1] 1 2 3 4 5 6 7 8 9

但是,如果你想保留一个矩阵结构,那么对 dim 属性的这种修改将是有效的:

dim(m) <- c(dim(m)[1]*dim(m)[2], 1)
m
      [,1]
 [1,]    1
 [2,]    2
 [3,]    3
 [4,]    4
 [5,]    5
 [6,]    6
 [7,]    7
 [8,]    8
 [9,]    9

会有更紧凑的方法来获取维度的乘积,但上述方法强调了 dim 属性是矩阵的二元向量。在该示例中获得“9”的其他方法包括:

> prod(dim(m))
[1] 9
> length(m)
[1] 9

【讨论】:

  • 你可以通过 cbind(c(m)) 使其成为单列矩阵
  • @hadley 好的,那么 prod(dim(m)) 呢?
  • dim(m) &lt;- c(prod(dim(m)), 1) 更好一些,可以扩展到任意数量的维度`
  • 这就是我想让读者做的事情。代码prod(dim(m)) 是作为笨拙的替代品提供的:dim(m)[1]*dim(m)[2] 作为到达 9 的一种方式。它总是打算进入dim(m)&lt;-c(prod(dim(m)), 1),我想这就是为什么我无法理解你的评论。
  • 对于拥有data.frameunlist(df) 的任何人都有效。
【解决方案2】:

一个可能的解决方案,但不使用 reshape2:

> m <- matrix(c(1:9), ncol = 3)
> m
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
> as.vector(m)
[1] 1 2 3 4 5 6 7 8 9

【讨论】:

  • as.vector(m) 的速度大约是 c(m) 的一半 - 并不是说​​时间在这里很重要。
【解决方案3】:

R 伙计们来吧,让我们给 OP 一个 reshape2 解决方案:

> m <- matrix(c(1:9), ncol = 3)
> melt(m)$value
[1] 1 2 3 4 5 6 7 8 9

我只是懒得去测试它比 c(m) 慢了多少。不过是一样的:

> identical(c(m),melt(m)$value)
[1] TRUE

[编辑:哦,我在开玩笑吧:]

> system.time(for(i in 1:1000){z=melt(m)$value})
   user  system elapsed 
  1.653   0.004   1.662 
> system.time(for(i in 1:1000){z=c(m)})
   user  system elapsed 
  0.004   0.000   0.004 

【讨论】:

  • 在 1000 x 1000 矩阵上进行测试时,重塑解决方案的速度要慢几个数量级......正如您通过编辑看到的那样。 ;-)
  • +1 时间。有趣的重塑黑客虽然,我不会想到它。出于显而易见的原因;-)
  • 仅供娱乐:reshape2::melt 比 reshape::melt 快约 25%(10000 次重复约 7.7 秒对 10.3 秒),但仍比 c(m) 慢约 400 倍。 .
【解决方案4】:

as.vector(m) 应该比 c(m) 更高效:

> library(rbenchmark)
> m <- diag(5000)
> benchmark(
+   vect = as.vector(m), 
+   conc = c(m), 
+   replications=100
+ )
  test replications elapsed relative user.self sys.self user.child sys.child
2 conc          100  12.699    1.177     6.952    5.754          0         0
1 vect          100  10.785    1.000     4.858    5.933          0         0

【讨论】:

    【解决方案5】:

    一种更简单的方法是使用函数“sapply”(或者同样可以使用“for”循环)

     m <- matrix(c(1:9), ncol = 3)
     (m1 <- as.numeric(sapply(1:NROW(m), function(i)(m[,i]))))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-08
      • 2014-03-01
      • 1970-01-01
      • 2014-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多