R’da sıklıkla kullanılan değişken tiplerinden biri olan data.frame oldukça kullanışlıdır ve farklı değişken tiplerini içerisinde barındırabilir. Fakat data.frame ile çalışmak büyük verilerde performans düşüklüğüne de yol açabilir. Bu yazıda zaman zaman data.frame yerine değerlendirilebilecek iki alternatiften bahsedeceğim: Matrix ve data.table.
Bir matrix yalnızca sayısal değişkenleri içerisinde barındırabilirken data.frame, bahsettiğimiz gibi birden fazla değişken tipini tutabiliyor. Bu nedenle de bu alternatif dahilinde performans karşılaştırmalarını sadece sayısal değerler içeren bir data.frame ile aynı değerlere sahip matrix arasında yapacağız.
data <- rnorm(1E4*1000)
dim(data) <- c(1E4, 1000)
class(data)
# [1] "matrix" "array"
system.time(data_rs1 <- rowSums(data))
# user system elapsed
# 0.03 0.00 0.03
data_df <- data.frame(data)
system.time(data_rs2 <- rowSums(data_df))
# user system elapsed
# 0.06 0.01 0.07
“data" adlı değişkenin matrix tipinde olduğu ve rowSums(data) fonksiyonu ile satırlardaki değerlerin toplandığı örnek ile aynı verinin data.frame tipinde olduğu senaryoyu karşılaştıralım. “elapsed” değerlerine bakılarak performans farkı rahatlıkla gözlemlenebilir.
Bir başka alternatif ise bir R paketi olan data.table. Bu paket data.frame’in gelişmiş versiyonu olan data.table veri tipini sunuyor. Özetle data.frame ile yapılabilecek her şeyi data.table ile yapmak mümkün. Avantajı ise işlemlerin çok daha hızlı gerçekleşmesi. Veriyi almak, yazdırmak, işlemek data.table veri tipi ve ona özel fonksiyonlarla çok daha yüksek performanslı bir biçimde gerçekleşebiliyor. Ek olarak bu veri tipinin veri manipülasyonlarında da oldukça hızlı olduğunu ifade etmek gerek. Yaklaşık 450 bin satırlık bir veriyi hem read.csv hem de bu fonksiyonun data.table versiyonu olan fread ile alıp performanslarını karşılaştıralım.
system.time(dt <- read.csv(“data.csv”))
# user system elapsed
# 11.46 0.21 11.69
system.time(dt <- fread(“data.csv”))
# user system elapsed
# 0.66 0.00 0.66
dim(dt)
# [1] 439541 18
Gördüğünüz gibi fark hayli büyük.
Şimdi de bir başka örnek yapalım. data.frame ve dplyr paketi yardımıyla gerçekleştirdiğimiz bir analizi, data.table ile yapalım. Aşağıda kullanılan veri 11 milyon satır ve 7 sütuna sahip. İki kod da tamamen aynı sonucu veriyor. Fakat performansları arasında ciddi bir fark var.
system.time(brand <- data % > % group_by(ID, CAT, BRAND) % > % summarise(count = n(), OrtFiyat = mean(PRICE), maxFiyat = max(PRICE), range = ((max(PRICE)— min(PRICE)) / min(PRICE))))
# user system elapsed
# 671.11 0.39 671.80
system.time(brand <- data[, .(count = .N, OrtFiyat = mean(PRICE), maxFiyat = max(PRICE), range = ((max(PRICE)— min(PRICE)) / min(PRICE))), by = list(ID, CAT, BRAND), ])
# user system elapsed
# 37.95 0.03 37.98
Aradaki performans farkının kaç kat olduğu ortada. dplyr bize büyük bir esneklik sağlıyor ve şüphesiz syntax’i data.table’a göre daha kolay. Fakat bir kez alıştıktan sonra data.table çok daha kullanışlı gelebilir. Özellikle de bu örnekte olduğu gibi büyük verilerde.
Veri bilimi hakkında daha geniş ve kapsamlı bilgiye erişmek, kariyerinizde fark yaratacak adımlar atmak isterseniz Miuul'un sunduğu Data Scientist Path eğitimine göz atabilirsiniz.