Ar-hızlı döngü işlemi
bir veri üzerinde yineleme bir fonksiyon yazdım R. büyük bir performans sorunu var.çerçeve nesnesi. Bu sadece bir veri için yeni bir sütun ekler.çerçeve ve heyecanla beklediğim birikir. (basit bir işlem). Verileri.çerçeve 850.000 satır yuvarlak vardır. Benim PC hala yaklaşık 10 saat çalışıyor ve zamanı hakkında hiçbir fikrim yok.
dayloop2 <- function(temp){
for (i in 1:nrow(temp)){
temp[i,10] <- i
if (i > 1) {
if ((temp[i,6] == temp[i-1,6]) & (temp[i,3] == temp[i-1,3])) {
temp[i,10] <- temp[i,9] temp[i-1,10]
} else {
temp[i,10] <- temp[i,9]
}
} else {
temp[i,10] <- temp[i,9]
}
}
names(temp)[names(temp) == "V10"] <- "Kumm."
return(temp)
}
Bu işlemi hızlandırmak için nasıl herhangi bir fikir ?
CEVAP
Etkisizliği sorunu ve kök dizin oluşturma veri büyük.çerçeve, temp[,]
kullandığınız tüm bu çizgiler ...
Bunu mümkün olduğunca uzak durmaya çalışın. Fonksiyon, dizin oluşturma ve değiştirme aldımversion_A
dayloop2_A <- function(temp){
res <- numeric(nrow(temp))
for (i in 1:nrow(temp)){
res[i] <- i
if (i > 1) {
if ((temp[i,6] == temp[i-1,6]) & (temp[i,3] == temp[i-1,3])) {
res[i] <- temp[i,9] res[i-1]
} else {
res[i] <- temp[i,9]
}
} else {
res[i] <- temp[i,9]
}
}
temp$`Kumm.` <- res
return(temp)
}
Gördüğünüz gibi sonuçlar toplandığı vektör res
yaratıyorum. Sonunda ben 10 ** Ekle ve isimleri karışıklık gerek yok.
Nasıl iyi mi?
Ben 1000 1.000-10.000 nrow
11 *her fonksiyonu çalıştırın ve system.time
ile zaman ölçmek
X <- as.data.frame(matrix(sample(1:10, n*9, TRUE), n, 9))
system.time(dayloop2(X))
Sonucudur
Sürümü nrow(X)
katlanarak bağlı olduğunu görebilirsiniz. Değiştirilmiş Sürüm doğrusal ilişki vardır, ve lm
basit model 850,000 satır için hesaplama 6 dakika ve 10 saniye sürer tahmin.
Vektörleştirme güç
Onların cevapları Shane ve Calimo devletler olarak vektörleştirme daha iyi performans için bir anahtardır. Kodlarınızı döngü dışında hareket olabilir:
- klima
- sonuçları
temp[i,9]
) başlatma
Bu kod yol açar
dayloop2_B <- function(temp){
cond <- c(FALSE, (temp[-nrow(temp),6] == temp[-1,6]) & (temp[-nrow(temp),3] == temp[-1,3]))
res <- temp[,9]
for (i in 1:nrow(temp)) {
if (cond[i]) res[i] <- temp[i,9] res[i-1]
}
temp$`Kumm.` <- res
return(temp)
}
10.000 10.000 100.000 bu işlevleri nrow
bu kez sonucu karşılaştırın.
Ayarlama ayarlanmış
Başka bir tweak res[i]
döngü bir indeksleme temp[i,9]
i-th döngü tekrarında aynı olan) değiştirmek için.
Yeniden indeksleme, vektör ve dizin arasındaki fark data.frame
.
Üzerinde durumu uygun olanlar için 23* *ama sadece tüm döngü gerek yok gördüğünüz gibi döngü baktığında. ikinci şey:
İşte başlıyoruz
dayloop2_D <- function(temp){
cond <- c(FALSE, (temp[-nrow(temp),6] == temp[-1,6]) & (temp[-nrow(temp),3] == temp[-1,3]))
res <- temp[,9]
for (i in (1:nrow(temp))[cond]) {
res[i] <- res[i] res[i-1]
}
temp$`Kumm.` <- res
return(temp)
}
Yüksek kazanç sağlayan performans veri yapısına bağlıdır. Tam - on TRUE
yüzde kondüsyon.
Benim simüle veri için bir ikinci aşağıda 850,000 satır için hesaplama zamanı alır.
Ben daha fazla istiyorum, yapılabilir: en az iki şey görüyorum
C
bir kod koşullu cumsum yapmak için yazmaeğer verilerinizi max dizi döngü sırasında vectorized için değiştirebilirsiniz büyük değil o zaman eğer, bir şey gibi
while (any(cond)) { indx <- c(FALSE, cond[-1] & !cond[-n]) res[indx] <- res[indx] res[which(indx)-1] cond[indx] <- FALSE }
Simülasyonları ve şekiller için kullanılan kod available on GitHub.
Neden AddRange daha hızlı foreach döng...
.Döngü daha hızlı çalışır NET,' v...
Kıyaslama - neden ikinci döngü daha hı...
'döngü için en hızlı yol boyunca ...
Bir Dizi çoğaltmak için Javascript en ...