মনে করুন আপনি ডেটা আকারের ফ্রেম আগেই জানেন না। এটি কয়েক সারি বা কয়েক মিলিয়ন হতে পারে। আপনার কিছু ধরণের ধারক থাকা দরকার, যা গতিশীলভাবে বৃদ্ধি পায়। আমার অভিজ্ঞতা এবং সমস্ত সম্পর্কিত উত্তর বিবেচনায় নিয়ে এসও আমি 4 স্বতন্ত্র সমাধান নিয়ে আসছি:
rbindlist
ডেটা.ফ্রেমে
প্রয়োজনে যখন দ্রুত টেবিলটি দ্বিগুণ করার সাথে এটির data.table
দ্রুত set
অপারেশন ব্যবহার করুন এবং এর সাথে জুটি দিন।
RSQLite
মেমরিতে রাখা টেবিলটি ব্যবহার করুন এবং যুক্ত করুন ।
data.frame
ডেটা.ফ্রেম সংরক্ষণ করার জন্য কাস্টম এনভায়রনমেন্ট (যার রেফারেন্স সিমানটিক রয়েছে) বৃদ্ধি এবং ব্যবহারের নিজস্ব ক্ষমতা যাতে এটি ফিরতি অনুলিপি করা হয় না।
ছোট এবং বৃহত সংখ্যক সংযুক্ত সংযুক্ত সারির জন্য সমস্ত পদ্ধতির একটি পরীক্ষা এখানে রয়েছে। প্রতিটি পদ্ধতির সাথে এর সাথে সম্পর্কিত 3 টি কার্য রয়েছে:
create(first_element)
যেটি রাখার সাথে সাথে উপযুক্ত ব্যাকিং অবজেক্টকে ফিরিয়ে দেয় first_element
।
append(object, element)
element
এটি টেবিলের শেষে যুক্ত করে (উপস্থাপিত object
)।
access(object)
data.frame
সমস্ত sertedোকানো উপাদান সঙ্গে পায় ।
rbindlist
ডেটা.ফ্রেমে
এটি বেশ সহজ এবং সোজা-এগিয়ে:
create.1<-function(elems)
{
return(as.data.table(elems))
}
append.1<-function(dt, elems)
{
return(rbindlist(list(dt, elems),use.names = TRUE))
}
access.1<-function(dt)
{
return(dt)
}
data.table::set
যখন প্রয়োজন হয় তখন ম্যানুয়ালি টেবিল দ্বিগুণ করা।
আমি একটি rowcount
বৈশিষ্ট্যে টেবিলের আসল দৈর্ঘ্য সঞ্চয় করব ।
create.2<-function(elems)
{
return(as.data.table(elems))
}
append.2<-function(dt, elems)
{
n<-attr(dt, 'rowcount')
if (is.null(n))
n<-nrow(dt)
if (n==nrow(dt))
{
tmp<-elems[1]
tmp[[1]]<-rep(NA,n)
dt<-rbindlist(list(dt, tmp), fill=TRUE, use.names=TRUE)
setattr(dt,'rowcount', n)
}
pos<-as.integer(match(names(elems), colnames(dt)))
for (j in seq_along(pos))
{
set(dt, i=as.integer(n+1), pos[[j]], elems[[j]])
}
setattr(dt,'rowcount',n+1)
return(dt)
}
access.2<-function(elems)
{
n<-attr(elems, 'rowcount')
return(as.data.table(elems[1:n,]))
}
এসকিউএল দ্রুত রেকর্ড সন্নিবেশের জন্য অনুকূলিত করা উচিত, তাই আমার প্রাথমিকভাবে RSQLite
সমাধানের জন্য উচ্চ আশা ছিল
এটি মূলত অনুরূপ থ্রেডে কার্স্টেন ডাব্লু উত্তর কপি এবং পেস্ট করুন।
create.3<-function(elems)
{
con <- RSQLite::dbConnect(RSQLite::SQLite(), ":memory:")
RSQLite::dbWriteTable(con, 't', as.data.frame(elems))
return(con)
}
append.3<-function(con, elems)
{
RSQLite::dbWriteTable(con, 't', as.data.frame(elems), append=TRUE)
return(con)
}
access.3<-function(con)
{
return(RSQLite::dbReadTable(con, "t", row.names=NULL))
}
data.frame
এর নিজস্ব সারি-সংযোজন + কাস্টম পরিবেশ।
create.4<-function(elems)
{
env<-new.env()
env$dt<-as.data.frame(elems)
return(env)
}
append.4<-function(env, elems)
{
env$dt[nrow(env$dt)+1,]<-elems
return(env)
}
access.4<-function(env)
{
return(env$dt)
}
পরীক্ষার স্যুট:
সুবিধার জন্য আমি তাদের সমস্তকে পরোক্ষ কলিংয়ের সাথে কভার করতে একটি পরীক্ষা ফাংশন ব্যবহার করব। (আমি চেক করেছি: do.call
ফাংশনগুলিকে সরাসরি কল করার পরিবর্তে ব্যবহার করা কোড চালানো আর দীর্ঘায়িত করে না)।
test<-function(id, n=1000)
{
n<-n-1
el<-list(a=1,b=2,c=3,d=4)
o<-do.call(paste0('create.',id),list(el))
s<-paste0('append.',id)
for (i in 1:n)
{
o<-do.call(s,list(o,el))
}
return(do.call(paste0('access.', id), list(o)))
}
আসুন এন = 10 সন্নিবেশের জন্য পারফরম্যান্সটি দেখুন।
আমি এমন একটি 'প্লেসবো' ফাংশনও যুক্ত করেছি (প্রত্যয় সহ 0
) যা কিছু করে না - কেবল পরীক্ষার সেটআপের ওভারহেড পরিমাপ করার জন্য।
r<-microbenchmark(test(0,n=10), test(1,n=10),test(2,n=10),test(3,n=10), test(4,n=10))
autoplot(r)
1E5 সারিগুলির জন্য (ইনটেল (আর) কোর (টিএম) i7-4710HQ সিপিইউ @ 2.50GHz উপর পরিমাপ করা হয়েছে):
nr function time
4 data.frame 228.251
3 sqlite 133.716
2 data.table 3.059
1 rbindlist 169.998
0 placebo 0.202
দেখে মনে হচ্ছে এটি এসকিউএল-ভিত্তিক ক্ষয়, যদিও বড় ডেটাতে কিছুটা গতি ফিরে আসে, তথ্যের কাছাকাছি কোথাও নেই t টেবিল + ম্যানুয়াল এক্সফোনেনশিয়াল বৃদ্ধি। পার্থক্যটি প্রায় দুটি আদেশের মাত্রার!
সারসংক্ষেপ
আপনি যদি জানেন যে আপনি সংখ্যার কম সংখ্যক সারি সংযোজন করবেন (n <= 100), এগিয়ে যান এবং সহজতম সমাধানটি ব্যবহার করুন: বন্ধনী সারণি ব্যবহার করে কেবল ডাটা.ফ্রেমকে সারিগুলি নির্ধারণ করুন এবং ডেটা.ফ্রেমটি এই বিষয়টি উপেক্ষা করুন ignore প্রাক জনবহুল না।
অন্য যে কোনও কিছুর জন্য data.table::set
ডেটা ব্যবহার করুন এবং বড় করুন t তাড়াতাড়ি টেবিল করুন (যেমন আমার কোড ব্যবহার করে)।