R'da yüksek performanslı programlama IV: Veri yapıları

R'da yüksek performanslı programlama IV: Veri yapıları

Bu yazıda R programlamada veri yapılarının kod performansı üzerindeki etkilerini ele alıyoruz.
Onur Boyar08 Nis 2021

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.

Miuul topluluğunun bir parçası ol!

Abone ol butonuna tıklayarak Miuul'dan pazarlama ve haber içerikleri almayı onaylıyorum.