आर

2012-11-08 21 views
7

में मैट्रिक्स के कॉलम के भारित योग को लेने का सबसे तेज़ तरीका मुझे मैट्रिक्स के प्रत्येक कॉलम के भारित योग की आवश्यकता है।आर

data <- matrix(1:2e7,1e7,2) # warning large number, will eat up >100 megs of memory 
weights <- 1:1e7/1e5 
system.time(colSums(data*weights)) 
system.time(apply(data,2,function(x) sum(x*weights))) 
all.equal(colSums(data*weights), apply(data,2,function(x) sum(x*weights))) 

आमतौर पर colSums(data*weights) लागू कॉल से तेज़ है।

मैं अक्सर यह ऑपरेशन करता हूं (एक बड़े मैट्रिक्स पर)। इसलिए सबसे कुशल कार्यान्वयन पर सलाह की तलाश है। आदर्श रूप में, अगर हम colSums (या rowSums) के वजन को पार कर सकते हैं तो बहुत अच्छा होता।

धन्यवाद, किसी भी अंतर्दृष्टि की सराहना करें!

उत्तर

8

colSums और * दोनों आंतरिक या आदिम कार्य हैं और apply दृष्टिकोण की तुलना में बहुत तेजी से

एक और दृष्टिकोण आप की कोशिश कर सकते कुछ बुनियादी मैट्रिक्स बीजगणित उपयोग करने के लिए है हो जाएगा के रूप में आप देख रहे हैं

weights %*% data 

के लिए मैट्रिक्स गुणात्मक विधि तेजी से प्रतीत नहीं होती है लेकिन यह data

system.time({.y <- colSums(data * weights)}) 
## user system elapsed 
## 0.12 0.03 0.16 


system.time({.x <- weights %*% data}) 
## user system elapsed 
## 0.20 0.05 0.25 
का अस्थायी ऑब्जेक्ट बनाने से बच जाएगी
+0

धन्यवाद, समझ में आता है। – Anirban

3

आरसीपीपी एक प्रदर्शन लाभ (विशेष रूप से कॉलम की एक बड़ी संख्या के साथ) की ओर जाता है।

library(Rcpp) 
library(inline) 
src <- ' 
Rcpp::NumericMatrix dataR(data); 
Rcpp::NumericVector weightsR(weights); 
int ncol = dataR.ncol(); 
Rcpp::NumericVector sumR(ncol); 
for (int col = 0; col<ncol; col++){ 
    sumR[col] = Rcpp::sum(dataR(_, col)*weightsR); 
} 
return Rcpp::wrap(sumR);' 

weighted.colSums <- cxxfunction(
    signature(data="numeric", weights="numeric"), src, plugin="Rcpp") 
data <- matrix(as.numeric(1:1e7),1e5,100) # warning large object 
weights <- 1:1e5/1e5 
all.equal(colSums(data*weights), weighted.colSums(data, weights)) 
## [1] TRUE 
print(system.time(colSums(data*weights))) 
## user system elapsed 
## 0.065 0.001 0.064 
print(system.time(as.vector(weighted.colSums(data, weights)))) 
## user system elapsed 
## 0.019 0.001 0.019 
all.equal(as.vector(weights %*% data), weighted.colSums(data, weights)) 
## [1] TRUE 
print(system.time(weights %*% data)) 
## user system elapsed 
## 0.066 0.001 0.066