সবচেয়ে বড় সমস্যা এবং অকার্যকরতার মূলটি হ'ল ডেটা.ফ্রেমকে সূচীকরণ করা, আমি বোঝাতে চাইছি আপনি যেখানে ব্যবহার করেন এই সমস্ত লাইন temp[,]
।
এটি যথাসম্ভব এড়াতে চেষ্টা করুন। আমি আপনার ফাংশন নিয়েছি, সূচী পরিবর্তন এবং এখানে সংস্করণ_আ
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)
}
আপনি দেখতে পাচ্ছেন যে আমি ভেক্টর তৈরি করেছি res
যা ফলাফল সংগ্রহ করে। শেষে আমি এটিকে যুক্ত data.frame
করব এবং নামগুলির সাথে আমার গণ্ডগোলের দরকার নেই। তাহলে এটি কতটা ভাল?
আমি একে ফাংশন চালানোর data.frame
সঙ্গে nrow
1000 থেকে 1000 দ্বারা 10,000 প্রয়োজন এবং সঙ্গে সময় পরিমাপsystem.time
X <- as.data.frame(matrix(sample(1:10, n*9, TRUE), n, 9))
system.time(dayloop2(X))
ফলাফল হয়
আপনি দেখতে পাচ্ছেন যে আপনার সংস্করণটি দ্রুত থেকে নির্ভর করে nrow(X)
। পরিবর্তিত সংস্করণটির লিনিয়ার সম্পর্ক রয়েছে এবং সাধারণ lm
মডেলটি অনুমান করে যে 850,000 সারিগুলির জন্য গণনা 6 মিনিট 10 সেকেন্ড সময় নেয় takes
ভেক্টরাইজেশন শক্তি
শেন এবং ক্যালিমো যেহেতু তাদের জবাব দেয় ভেক্টরাইজেশন আরও ভাল পারফরম্যান্সের মূল চাবিকাঠি। আপনার কোড থেকে আপনি লুপের বাইরে যেতে পারেন:
- কন্ডিশনার
- ফলাফলের সূচনা (যা হ'ল
temp[i,9]
)
এটি এই কোড বাড়ে
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)
}
এই ফাংশনগুলির জন্য ফলাফলের তুলনা করুন, এবার nrow
10,000 থেকে 10,000 করে 10,000 করে।
টিউন করা সুর
আরেকটি ত্বক হ'ল একটি লুপকে ইনডেক্সিংয়ে পরিবর্তন temp[i,9]
করা res[i]
(যা আই-ত্র লুপ পুনরাবৃত্তিতে ঠিক একই)। এটি আবার একটি ভেক্টরকে সূচীকরণ এবং একটি সূচকের মধ্যে পার্থক্য data.frame
।
দ্বিতীয় জিনিস: আপনি যখন লুপটি দেখেন তখন আপনি দেখতে পাবেন যে সমস্তর উপর লুপ করার দরকার নেই i
, তবে কেবল সেই অবস্থার জন্য উপযুক্ত।
সুতরাং এখানে আমরা যেতে
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)
}
পারফরম্যান্স যা আপনি অত্যন্ত অর্জন করেন তা কোনও ডেটা স্ট্রাকচারের উপর নির্ভর করে। অবিকল - TRUE
শর্তের মানের শতাংশের উপরে । আমার সিমুলেটেড ডেটার জন্য এটি এক সেকেন্ডের নিচে 850,000 সারিগুলির জন্য গণনার সময় নেয়।
আমি চাই আপনি আরও যেতে পারেন, আমি কমপক্ষে দুটি জিনিস যা করতে পারি তা দেখতে পাচ্ছি:
C
শর্তসাপেক্ষ cumsum করতে একটি কোড লিখুন
যদি আপনি জানেন যে আপনার ডেটা সর্বাধিক সিকোয়েন্স বড় নয় তবে আপনি লুপটি ভেক্টরাইজড অবস্থায় পরিবর্তন করতে পারবেন, এমন কিছু
while (any(cond)) {
indx <- c(FALSE, cond[-1] & !cond[-n])
res[indx] <- res[indx] + res[which(indx)-1]
cond[indx] <- FALSE
}
কোড সিমিউলেশন ও পরিসংখ্যান জন্য ব্যবহার করা হয় GitHub থেকে পাওয়া ।