2016-01-08 203 views
2

對矩陣執行的過程(如果需要可以將其轉換爲數據幀或某種其他形式)後,我想查看原始矩陣出現在新矩陣的任何地方。將一個矩陣中的每一行與另一個矩陣的每一行進行比較

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循環的解決方案,但它會採取20萬* 20萬太久太久......

#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個月左右,這是朝正確方向邁出的一步!

+1

嘗試'vapply(seq_len(nrow(Firstmatrix)),函數(ⅰ)anyDuplicated(rbind(Firstmatrix [I],Secondmatrix [I,])),0)'或'!rowSums(Firstmatrix! = Secondmatrix)' – akrun

回答

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 
相關問題