【问题标题】:Comparing every row in one matrix with every row of another matrix将一个矩阵中的每一行与另一个矩阵的每一行进行比较
【发布时间】:2016-01-08 17:39:19
【问题描述】:

在对矩阵执行处理之后(如果需要,可以将其转换为数据帧或其他形式),我想查看原始矩阵的行是否出现在新矩阵的任何位置。

E.g.Matrix1=(1,1,1,1,1;
             2,2,2,2,2;
             3,3,3,4,4;
             5,5,5,6,6)

我想知道(1,1,1,1,1),(2,2,2,2,2)等是否出现在Matrix2中。我还想知道矩阵 2 中是否出现非常相似的行,例如 (1,1,1,1,8) 或 (2,2,2,2,7)。具体来说,我所说的相似是指它们只有 1 或 2 个不同的列条目(对于 11 列,它们有 9 个或更多列条目相同)。

我遇到的主要问题是处理时间,我只有 11 列用于比较矩阵,但两个矩阵都有大约 200,000 行,因此我将比较 200,000 行和其他 200,000 行。 我有一个带有 for 循环的解决方案,但是 200,000*200,000 会花费很长时间......

#Reproducible Example
Firstmatrix<-t(matrix(c(1,1,1,1,1,
                        2,2,2,2,2,
                        3,3,3,3,3,
                        0,0,0,0,0,
                        2,2,2,2,2,
                        4,4,4,4,4,
                        1,2,3,4,5,
                        1,1,1,1,6),
                        nrow=5,ncol=8))

Secondmatrix<-t(matrix(c(1,1,1,1,1,
                         1,1,1,1,1,
                         2,2,2,2,2,
                         3,3,3,3,3,
                         4,4,4,5,5,
                         5,5,5,4,4,
                         6,1,1,1,3,
                         3,1,1,1,6),
                         nrow=5,ncol=8))

#these matrices will be in a similar form to example above
#To time test larger matrices with more columns I have used:

Firstmatrix<-Firstmatrix[rep(seq_len(8), each=100),]
Secondmatrix<-Secondmatrix[rep(seq_len(8), each=100),]
#which create matrices with 100x as many rows and
t1<-Sys.time()
t2<-Sys.time()
t2-t1 
#either side of the code to measure how long it takes    

#I came up with:

Column.entries.in.common<-matrix(NA,nrow=nrow(Firstmatrix),ncol=1)
Maximum.Column.entries.in.common<-matrix(NA,nrow=nrow(Firstmatrix),ncol=1)

for (i in 1:nrow(Firstmatrix))
{
for (j in 1:nrow(Secondmatrix))
{
Column.entries.in.common[j]<-sum(Firstmatrix[i,]==Secondmatrix[j,])

Maximum.Column.entries.in.common[i]<-max(Column.entries.in.common)
}
}

它为“Firstmatrix”中的每一行生成一个向量,以及它与“Secondmatrix”中的任何行共有的最大列数,它适用于每个矩阵上的几千行,但赢了运行 200k*200k 是不可行的。我知道我可能应该使用 mapply,但不确定如何指定它将对“Firstmatrix”的每一行与“Secondmatrix”的每一行进行比较。以前的尝试只是将 Firstmatrix 的每个元素与 Secondmatrix 进行了比较。

任何帮助将不胜感激。我知道这需要大量计算,因此总是需要一段时间才能运行,但是任何比我当前的代码更快的代码(我认为这需要大约 4 个月)都是朝着正确方向迈出的一步!

【问题讨论】:

  • 试试vapply(seq_len(nrow(Firstmatrix)), function(i) anyDuplicated(rbind(Firstmatrix[i,], Secondmatrix[i,])),0)!rowSums(Firstmatrix!=Secondmatrix)

标签: r matrix dataframe compare rows


【解决方案1】:

这应该更快,因为它只对一组行执行非向量化迭代,而其余行是向量化的。这使用了列连续存储的事实,因此At[, i] 将被适当地回收以执行== 操作。另一个好处是获取列可能比获取行更快。

At <- t(Firstmatrix)
Bt <- t(Secondmatrix)
mx <- sapply(1:ncol(At), function(i) max(colSums(At[, i] == Bt)))

all.equal(mx, c(Maximum.Column.entries.in.common))
## [1] TRUE

时机

这是一个时间比较,它显示对于给定的数据,它运行时间大约是经过时间的 1/60。

system.time({
  Column.entries.in.common<-matrix(NA,nrow=nrow(Firstmatrix),ncol=1)
  Maximum.Column.entries.in.common<-matrix(NA,nrow=nrow(Firstmatrix),ncol=1)
  for (i in 1:nrow(Firstmatrix))
  {
    for (j in 1:nrow(Secondmatrix))
    {
    Column.entries.in.common[j]<-sum(Firstmatrix[i,]==Secondmatrix[j,])
    Maximum.Column.entries.in.common[i]<-max(Column.entries.in.common)
    }
  }
})
##   user  system elapsed 
##  10.99    0.00   11.12 


system.time({
  At <- t(Firstmatrix)
  Bt <- t(Secondmatrix)
  mx <- sapply(1:ncol(At), function(i) max(colSums(At[, i] == Bt)))
})
##   user  system elapsed 
##   0.19    0.00    0.19 

【讨论】:

    猜你喜欢
    • 2019-11-15
    • 1970-01-01
    • 2019-03-14
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多