2017-06-02 114 views
2

將兩個矩陣(一個和兩個)匹配在一起並提取匹配矩陣二的索引的快速方法是什麼?矩陣二很大(數百到數千行)。用另一個矩陣對矩陣索引進行子集化

one 
[,1] [,2] 
    9 11 
    13 2 


head(two) 
    [,1][,2] 
[1,] 9 11 
[2,] 11 9 
[3,] 2 3 
[4,] 13 2 
[5,] 2 4 
[6,] 3 3 

輸出應爲(注意指數2怎麼不是一個輸出值),這樣做的

1 4 
+0

快速計算機或爲程序員?如果你只需要做一次,那麼成千上萬的行並不是那麼多。 – Aaron

+0

可能的重複https://stackoverflow.com/questions/12463687/subset-a-matrix-by-values-in-the-other-matrix – akrun

回答

1

你可以寫一個C++循環做到這一點相當快

library(Rcpp) 

cppFunction('NumericVector matrixIndex(NumericMatrix m1, NumericMatrix m2){ 

int m1Rows = m1.nrow(); 
int m2Rows = m2.nrow(); 
NumericVector out; 

for (int i = 0; i < m1Rows; i++){ 
    for (int j = 0; j < m2Rows; j++){ 

    if(m1(i, 0) == m2(j, 0) && m1(i, 1) == m2(j, 1)){ 
     //out[j] = (j+1); 
     out.push_back(j + 1); 
    } 
    } 
} 

return out; 

}') 

matrixIndex(m1, m2) 
[1] 1 4 

雖然我懷疑這會更快先預分配結果向量,東西像

cppFunction('NumericVector matrixIndex(NumericMatrix m1, NumericMatrix m2){ 

int m1Rows = m1.nrow(); 
int m2Rows = m2.nrow(); 
NumericVector out(m2Rows); 

for (int i = 0; i < m1Rows; i++){ 
    for (int j = 0; j < m2Rows; j++){ 

    if(m1(i, 0) == m2(j, 0) && m1(i, 1) == m2(j, 1)){ 
     out[j] = (j+1); 
     //out.push_back(j + 1); 
    } 
    } 
} 

return out; 

}') 

matrixIndex(m1, m2) 
[1] 1 0 0 4 0 0 
## 0 == nomatch. 
4

方式一:

a = apply(one, 1, paste0, collapse = "-") 
b = apply(two, 1, paste0, collapse = "-") 
match(a, b) 

#[1] 1 4 

我們所有的列粘貼在一起,按行明智的兩個矩陣,然後匹配它們以獲得相同的行。

僅供參考,

a 
#[1] "9-11" "13-2" 
b 
#[1] "9-11" "11-9" "2-3" "13-2" "2-4" "3-3" 
1

你不會說「快」你的意思是計算時間或人的時間。如果只需要進行一次,那麼如果優化人員時間,總體時間可能會最短,並且Ronak的答案將很難被擊敗,這是清晰而強大的。

如果數字都小於某個數字(例如,如您的示例數據中的100),則可以執行類似的操作,但使用算術將兩列組合在一起,然後進行匹配。我懷疑(但沒有測試過),這將比轉換爲字符向量更快。當然,其他算術選項也取決於你的情況。

a <- one[,1]*100 + one[,2] 
b <- two[,1]*100 + two[,2] 
match(a, b) 
0

我們可以使用%in%

which(do.call(paste, as.data.frame(two)) %in% do.call(paste, as.data.frame(one))) 
#[1] 1 4 
相關問題