SORU
29 AĞUSTOS 2011, PAZARTESİ


En hızlı büyük veri NAs değiştirmek için bir yol.tablo

data.table çok büyük bir kayıp değerleri ~200 k 200 satır ve sütunları kendi dağılmış. Yeniden kod sıfır değerleri NA bu mümkün olduğunca verimli bir şekilde yapmak istiyorum.

İki seçenek görüyorum
1: Bir veri Dönüştürmek.çerçeve, ve bir şey like this kullanın
2: serin bir veri bir tür.masa alt komut ayarı

Tip 1 oldukça etkili bir çözüm ile mutlu olacağım. Bir veri dönüştürme.çerçeve ve geri veri.tablo çok uzun sürmez.

CEVAP
30 AĞUSTOS 2011, Salı


Burada bir çözüm data.table's := operatör, Andrie ve Ramnath bina cevaplar. kullanıyor

require(data.table)  # v1.6.6
require(gdata)       # v2.8.2

set.seed(1)
dt1 = create_dt(2e5, 200, 0.1)
dim(dt1)
[1] 200000    200    # more columns than Ramnath's answer which had 5 not 200

f_andrie = function(dt) remove_na(dt)

f_gdata = function(dt, un = 0) gdata::NAToUnknown(dt, un)

f_dowle = function(dt) {     # see EDIT later for more elegant solution
    na.replace = function(v,value=0) { v[is.na(v)] = value; v }
    for (i in names(dt))
        eval(parse(text=paste("dt[,",i,":=na.replace(",i,")]")))
}

system.time(a_gdata = f_gdata(dt1)) 
   user  system elapsed 
 18.805  12.301 134.985 

system.time(a_andrie = f_andrie(dt1))
Error: cannot allocate vector of size 305.2 Mb
Timing stopped at: 14.541 7.764 68.285 

system.time(f_dowle(dt1))
  user  system elapsed 
 7.452   4.144  19.590     # EDIT has faster than this

identical(a_gdata, dt1)   
[1] TRUE

F_dowle başvuru dt1 güncelleştirilmiş olduğunu unutmayın. Eğer yerel bir kopyası gerekirse o copy fonksiyon için açık çağrı tüm veri kümesi yerel bir kopyasını yapmak için gereklidir. veri.Tablo setkey, key<- :=--yazın kopyalamayın.

Gelecek, hadi f_dowle zaman harcama nerede olduğunu görmek.

Rprof()
f_dowle(dt1)
Rprof(NULL)
summaryRprof()
$by.self
                  self.time self.pct total.time total.pct
"na.replace"           5.10    49.71       6.62     64.52
"[.data.table"         2.48    24.17       9.86     96.10
"is.na"                1.52    14.81       1.52     14.81
"gc"                   0.22     2.14       0.22      2.14
"unique"               0.14     1.36       0.16      1.56
... snip ...

Orada, na.replace ve birkaç kopya vektör ve vektör taramalar vardır is.na odaklanmak istiyorum. Bu oldukça kolay na küçük bir yazı ile ortadan kaldırılabilir.C vektörü başvurusu tarafından bu güncellemeler NA işlevi değiştirin. Bence en azından 20 saniye yarıya. Böyle bir işlev, herhangi bir R paketi var mı?

f_andrie başarısız nedeni dt1, bütün kopyalar yüzünden olabilir ya da mantıksal bir matris dt1, bütün birkaç kez kadar büyük oluşturur. Diğer 2 yöntem bir defada bir sütun üzerinde sadece kısa bir süre NAToUnknown baktı rağmen) çalışır.

EDİT(daha zarif bir çözüm olarak yorum Ramnath tarafından talep edilen) :

f_dowle2 = function(DT) {
    for (i in names(DT))
        DT[is.na(get(i)),i:=0,with=FALSE]
}

system.time(f_dowle2(dt1))
  user  system elapsed 
 6.468   0.760   7.250   # faster, too

identical(a_gdata, dt1)   
[1] TRUE

Bu başlangıç için böyle yaptım keşke!

EDİT2(1 yıl sonra)

Ayrıca set() var. Bu bir döngü içinde [,:=,] arama (küçük) yükü önler gibi sütun bir sürü sarhoş olmak için daha hızlı olabilir. set 22 ** bir loopable. ?set bkz.

f_dowle3 = function(DT) {
    # either of the following for loops

    # by name :
    for (j in names(DT))
        set(DT,which(is.na(DT[[j]])),j,0)

    # or by number (slightly faster than by name) :
    for (j in seq_len(ncol(DT)))
        set(DT,which(is.na(DT[[j]])),j,0)
}

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Gavin Hoey

    Gavin Hoey

    21 Aralık 2007
  • Klemens Torggler

    Klemens Torg

    11 Mart 2008
  • LiquidMusick

    LiquidMusick

    23 Aralık 2010