SORU
25 Mayıs 2010, Salı


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
3 HAZİRAN 2010, PERŞEMBE


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

performance

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.

performance

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.

performance

Ben daha fazla istiyorum, yapılabilir: en az iki şey görüyorum

  • C bir kod koşullu cumsum yapmak için yazma
  • eğ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.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • DeAdPiXel6667

    DeAdPiXel666

    2 Ocak 2010
  • Lin Steven

    Lin Steven

    17 EKİM 2006
  • psidot

    psidot

    2 Kasım 2006