r - একটি বৃহৎ data.table মধ্যে NAs প্রতিস্থাপন দ্রুততম উপায়
performance dataframe (6)
আমার কাছে একটি বৃহৎ data.table , অনেকগুলি অনুপস্থিত মান ~ 200 ক সারি এবং 200 টি কলাম জুড়ে ছড়িয়ে পড়েছে। আমি যতটা সম্ভব দক্ষতার সাথে zeros এ এনএ মান কোড কোড করতে চাই।
আমি দুটি বিকল্প দেখি:
1: একটি data.frame রূপান্তর, এবং এই মত কিছু ব্যবহার
2: কিছু ধরনের শীতল data.table সাব সেটিং কমান্ড
আমি টাইপ 1 এর মোটামুটি কার্যকর সমাধান নিয়ে খুশি হব। একটি ডেটা.ফ্রেমে রূপান্তরিত হচ্ছে এবং তারপরে একটি ডেটা.table তে ফিরে খুব বেশি সময় লাগবে না।
আমার বোঝা হল R তে দ্রুত ক্রিয়াকলাপের গোপন ভেক্টর ব্যবহার করা (অথবা অ্যারে, যা হুডের অধীনে ভেক্টর।)
এই সমাধানটিতে আমি একটি data.matrix
ব্যবহার করি। data.matrix
যা একটি array
তবে data.matrix
মতো কিছুটা আচরণ করে। এটি একটি অ্যারের কারণ, আপনি NA
এর প্রতিস্থাপনের জন্য একটি খুব সহজ ভেক্টর প্রতিস্থাপন ব্যবহার করতে পারেন:
একটি ছোট সাহায্যকারী ফাংশন NA
গুলি মুছে ফেলার জন্য। সারাংশ কোড একক লাইন। আমি শুধুমাত্র execution সময় পরিমাপ করতে এই কাজ।
remove_na <- function(x){
dm <- data.matrix(x)
dm[is.na(dm)] <- 0
data.table(dm)
}
একটি প্রদত্ত আকারের data.table
. data.table
তৈরি করার জন্য একটি ছোট সহায়ক ফাংশন।
create_dt <- function(nrow=5, ncol=5, propNA = 0.5){
v <- runif(nrow * ncol)
v[sample(seq_len(nrow*ncol), propNA * nrow*ncol)] <- NA
data.table(matrix(v, ncol=ncol))
}
একটি ছোট নমুনা উপর বিক্ষোভ:
library(data.table)
set.seed(1)
dt <- create_dt(5, 5, 0.5)
dt
V1 V2 V3 V4 V5
[1,] NA 0.8983897 NA 0.4976992 0.9347052
[2,] 0.3721239 0.9446753 NA 0.7176185 0.2121425
[3,] 0.5728534 NA 0.6870228 0.9919061 NA
[4,] NA NA NA NA 0.1255551
[5,] 0.2016819 NA 0.7698414 NA NA
remove_na(dt)
V1 V2 V3 V4 V5
[1,] 0.0000000 0.8983897 0.0000000 0.4976992 0.9347052
[2,] 0.3721239 0.9446753 0.0000000 0.7176185 0.2121425
[3,] 0.5728534 0.0000000 0.6870228 0.9919061 0.0000000
[4,] 0.0000000 0.0000000 0.0000000 0.0000000 0.1255551
[5,] 0.2016819 0.0000000 0.7698414 0.0000000 0.0000000
আমি এখানে আসতে পারব এমন সবচেয়ে সহজ উপায়:
dt[is.na(dt)] <- 0
এটি কার্যকরী এবং ফাংশন এবং অন্যান্য আঠালো কোড লিখতে কোন প্রয়োজন।
এখানে gdata
প্যাকেজে gdata
ব্যবহার করে একটি সমাধান। আমি বিশাল তথ্য টেবিল তৈরি করার জন্য আন্দ্রে এর সমাধান ব্যবহার করেছি এবং আন্দ্রে এর সমাধান সহ সময় তুলনা অন্তর্ভুক্ত করেছি।
# CREATE DATA TABLE
dt1 = create_dt(2e5, 200, 0.1)
# FUNCTIONS TO SET NA TO ZERO
f_gdata = function(dt, un = 0) gdata::NAToUnknown(dt, un)
f_Andrie = function(dt) remove_na(dt)
# COMPARE SOLUTIONS AND TIMES
system.time(a_gdata <- f_gdata(dt1))
user system elapsed
4.224 2.962 7.388
system.time(a_andrie <- f_Andrie(dt1))
user system elapsed
4.635 4.730 20.060
identical(a_gdata, g_andrie)
TRUE
ডেডিকেটেড ফাংশন ( nafill
/ setnafill
) যে উদ্দেশ্যে সাম্প্রতিক data.table
প্যাকেজ
install.packages("data.table", repos="https://Rdatatable.gitlab.io/data.table")
এটি সমান্তরাল ঠিকঠাক ঠিকঠাক ঠিকঠাক কলামগুলিতে প্রক্রিয়া করে যা পূর্বে পোস্ট বেঞ্চমার্কগুলি, তার সময়গুলি এখন পর্যন্ত দ্রুততম পদ্ধতির সাথে, এবং 40 কোরের মেশিন ব্যবহার করেও বাড়িয়েছে।
library(data.table)
create_dt <- function(nrow=5, ncol=5, propNA = 0.5){
v <- runif(nrow * ncol)
v[sample(seq_len(nrow*ncol), propNA * nrow*ncol)] <- NA
data.table(matrix(v, ncol=ncol))
}
f_dowle3 = function(DT) {
for (j in seq_len(ncol(DT)))
set(DT,which(is.na(DT[[j]])),j,0)
}
set.seed(1)
dt1 = create_dt(2e5, 200, 0.1)
dim(dt1)
#[1] 200000 200
dt2 = copy(dt1)
system.time(f_dowle3(dt1))
# user system elapsed
# 0.193 0.062 0.254
system.time(setnafill(dt2, fill=0))
# user system elapsed
# 0.633 0.000 0.020 ## setDTthreads(1) elapsed: 0.149
all.equal(dt1, dt2)
#[1] TRUE
set.seed(1)
dt1 = create_dt(2e7, 200, 0.1)
dim(dt1)
#[1] 20000000 200
dt2 = copy(dt1)
system.time(f_dowle3(dt1))
# user system elapsed
# 22.997 18.179 41.496
system.time(setnafill(dt2, fill=0))
# user system elapsed
# 39.604 36.805 3.798
all.equal(dt1, dt2)
#[1] TRUE
library(data.table)
DT = data.table(a=c(1,"A",NA),b=c(4,NA,"B"))
DT
a b
1: 1 4
2: A NA
3: NA B
DT[,lapply(.SD,function(x){ifelse(is.na(x),0,x)})]
a b
1: 1 4
2: A 0
3: 0 B
শুধু রেফারেন্সের জন্য, gdata বা data.matrix এর তুলনায় ধীর। তবে কেবলমাত্র data.table প্যাকেজ ব্যবহার করে এবং অ সংখ্যাসূচক এন্ট্রিগুলির সাথে মোকাবিলা করতে পারে।
> DT = data.table(a=LETTERS[c(1,1:3,4:7)],b=sample(c(15,51,NA,12,21),8,T),key="a")
> DT
a b
1: A 12
2: A NA
3: B 15
4: C NA
5: D 51
6: E NA
7: F 15
8: G 51
> DT[is.na(b),b:=0]
> DT
a b
1: A 12
2: A 0
3: B 15
4: C 0
5: D 51
6: E 0
7: F 15
8: G 51
>