দ্রুত ডেটাফ্রেম হিসাবে খুব বড় টেবিলগুলি পড়া


502

আমার কাছে খুব বড় টেবিল রয়েছে (৩০ কোটি সারি) যেটি আমি আর একটি ডেটাফ্রেম হিসাবে লোড করতে চাই তাতে read.table()প্রচুর সুবিধাজনক বৈশিষ্ট্য রয়েছে, তবে মনে হয় বাস্তবায়নে অনেক যুক্তি রয়েছে যা জিনিসগুলিকে ধীর করে দেবে। আমার ক্ষেত্রে, আমি ধরে নিচ্ছি যে কলামগুলির ধরণের সময় আগে আমার জানা আছে, টেবিলটিতে কোনও কলামের শিরোনাম বা সারি নাম নেই এবং এতে আমার চিন্তার মতো কোনও প্যাথলজিকাল অক্ষর নেই।

আমি জানি যে তালিকা হিসাবে টেবিলে পড়া scan()বেশ দ্রুত হতে পারে, যেমন:

datalist <- scan('myfile',sep='\t',list(url='',popularity=0,mintime=0,maxtime=0)))

তবে এটির একটি ডেটাফ্রেমে রূপান্তরিত করার আমার কয়েকটি প্রচেষ্টা 6 এর একটি ফ্যাক্টর দ্বারা উপরের কার্যকারিতা হ্রাস করে বলে মনে হচ্ছে:

df <- as.data.frame(scan('myfile',sep='\t',list(url='',popularity=0,mintime=0,maxtime=0))))

এটি করার আরও ভাল উপায় আছে? বা সমস্যার সম্পূর্ণ ভিন্ন পদ্ধতির?

উত্তর:


425

একটি আপডেট, বেশ কয়েক বছর পরে

এই উত্তরটি পুরানো, এবং আর এগিয়ে গেছে। read.tableকিছুটা দ্রুত চালানোর জন্য ট্যুইকিংয়ের মূল্যবান সামান্য সুবিধা রয়েছে। আপনার বিকল্পগুলি হ'ল:

  1. ব্যবহার vroomtidyverse প্যাকেজ থেকে vroomসরাসরি একটি আর tibble মধ্যে CSV / ট্যাবের-সীমা নির্দেশ ফাইল থেকে ডেটা আমদানি করার জন্য।

  2. ব্যবহার freadমধ্যে data.tableসরাসরি আর দেখুন মধ্যে CSV / ট্যাবের-সীমা নির্দেশ ফাইল থেকে ডেটা আমদানি করার জন্য mnel এর উত্তর

  3. ব্যবহার read_tableমধ্যে readr(এপ্রিল 2015 থেকে Cran তে) খুলুন। এটি অনেকটা freadউপরের মতো কাজ করে । রিডমি লিঙ্কে দুটি ফাংশন মধ্যে পার্থক্য (ব্যাখ্যা readrবর্তমানে হতে "1.5-2x ধীর" চেয়ে দাবি data.table::fread)।

  4. read.csv.rawথেকে iotoolsসিএসভি ফাইলগুলি দ্রুত পড়ার জন্য একটি তৃতীয় বিকল্প সরবরাহ করে।

  5. ফ্ল্যাট ফাইলের চেয়ে ডাটাবেসে আপনি যতটা ডেটা রাখতে পারবেন তা সংরক্ষণ করার চেষ্টা করছেন। (পাশাপাশি একটি উন্নততর স্থায়ী সংরক্ষণাগার মাধ্যমে হচ্ছে, তথ্য প্রয়োজন এবং আর থেকে একটি বাইনারি বিন্যাসে পাস করা হয়েছে, যা দ্রুততর।) read.csv.sqlমধ্যে sqldfপ্যাকেজ, বর্ণনা অনুযায়ী জেডি লং-এর উত্তর একটি অস্থায়ী SQLite ডাটাবেস অনুবাদ করে, এবং ডেটা আমদানি করে এবং তারপর সার্চ আর এও দেখুন: RODBCপ্যাকেজটি এবং DBIপ্যাকেজ পৃষ্ঠার বিপরীতে নির্ভর করে section MonetDB.Rআপনাকে এমন একটি ডেটা টাইপ দেয় যা ডেটা ফ্রেম বলে ভান করে তবে সত্যিকারের নীচে একটি MonetDB, কর্মক্ষমতা বৃদ্ধি করে। এর monetdb.read.csvফাংশন সহ ডেটা আমদানি করুন । dplyrআপনাকে বিভিন্ন ধরণের ডাটাবেসে সঞ্চিত ডেটা সহ সরাসরি কাজ করতে দেয়।

  6. বাইনারি ফর্ম্যাটগুলিতে ডেটা সংরক্ষণ করা কার্যকারিতা উন্নত করতেও কার্যকর হতে পারে। ব্যবহারের saveRDS/ readRDS(নীচে দেখুন), h5অথবা rhdf5HDF5 ফরম্যাট, অথবা প্যাকেজ write_fst/ read_fstথেকে fstপ্যাকেজ।


আসল উত্তর

আপনি পঠন-টেবিল ব্যবহার করেন বা স্ক্যান করুন না কেন চেষ্টা করার জন্য কয়েকটি সাধারণ জিনিস রয়েছে।

  1. আপনার ডেটাতে রেকর্ডের সংখ্যা সেট করুন nrows= ( ইন )।nmaxscan

  2. comment.char=""মন্তব্যগুলির ব্যাখ্যা বন্ধ করতে নিশ্চিত করুন ।

  3. প্রতিটি কলামের ক্লাসগুলি স্পষ্টভাবে colClassesইন-টি ব্যবহার করে সংজ্ঞা দিন read.table

  4. সেটিং multi.line=FALSEস্ক্যানের কার্যকারিতাও উন্নত করতে পারে।

যদি এগুলির কোনওটিই কাজ না করে, তবে কোন লাইনে জিনিসগুলি কমিয়ে দিচ্ছে তা নির্ধারণ করতে একটি প্রোফাইল প্যাকেজ ব্যবহার করুন । সম্ভবত আপনি read.tableফলাফলের উপর ভিত্তি করে একটি কাটা ডাউন সংস্করণ লিখতে পারেন ।

অন্য বিকল্পটি আপনার ডেটা আর এ পড়ার আগে এটি ফিল্টার করছে।

বা, যদি সমস্যাটি হয় যে আপনাকে এটি নিয়মিত পড়তে হবে, তবে একবারে ডেটা পড়তে এই পদ্ধতিগুলি ব্যবহার করুন, তারপরে বাইনারি ব্লব হিসাবে ডেটা ফ্রেম সংরক্ষণ করুন save saveRDS, তারপরে পরবর্তী সময় আপনি এটির সাথে দ্রুত পুনরুদ্ধার করতে পারেন load readRDS


4
রিচি টিপসের জন্য ধন্যবাদ। আমি কিছুটা পরীক্ষা করে দেখেছি এবং দেখে মনে হচ্ছে যে রিড.টেবিলের জন্য নরো এবং কোলক্লাস বিকল্পগুলি ব্যবহার করে পারফরম্যান্স লাভ বেশ সামান্য mod উদাহরণস্বরূপ, একটি M 7M সারি টেবিলটি পড়তে বিকল্পগুলি ছাড়াই 78 টি এবং অপশন সহ 67s লাগে। (দ্রষ্টব্য: টেবিলটিতে 1 টি অক্ষর কলাম, 4 টি সংখ্যক কলাম রয়েছে, এবং আমি কমেন্ট সিআর = '' এবং স্ট্রিংসএফ্যাক্টরস = ফলস ব্যবহার করে পড়েছি)। যখন সম্ভব (সংরক্ষণ করুন) এবং লোড () ব্যবহার করা একটি দুর্দান্ত টিপ - একবার সেভ () এর সাথে সঞ্চিত হলে, একই টেবিলে লোড হতে কেবল 12 সেকেন্ড সময় লাগে।
আয়তন

2
"পালক" প্যাকেজের একটি নতুন বাইনারি ফর্ম্যাট রয়েছে যা পাইথনের
পান্ডাস

4
আমি মনে করি আপনার প্যাকেজটির সাথে আপনার পোস্টটি আবার আপডেট করা দরকার feather। তথ্য পড়ার জন্য featherতুলনায় অনেক দ্রুত fread। উদাহরণস্বরূপ 4 জিবি ডেটাসেটে আমি সবেমাত্র লোড করেছি read_featherতার চেয়ে প্রায় 4.5 গুণ বেশি দ্রুত fread। তথ্য সংরক্ষণের fwriteজন্য এখনও দ্রুত। blog.dominodatalab.com/the-r-data-io-shoutout
জেড বোসন

2
তবে আরডিএসের তুলনায় ফাইলের আকারগুলি পালকের জন্য অনেক বড়। আমি মনে করি না এটি সংকোচনের সমর্থন করে। আরডিএস ফাইলটি 216 এমবি এবং পালক ফাইলটি 4 জিবি। তাই featherপড়ার জন্য দ্রুততর কিন্তু এটি একটি আরো অনেক স্টোরেজ স্পেস ব্যবহার করে।
জেড বোসন

@ জেডবসন আপনার যদি কোনও ফাইলে ডেটা ফ্রেম সংরক্ষণ করতে হয় যা আর এবং পাইথন উভয় থেকে অ্যাক্সেস করা যায় তবে featherএটি একটি ভাল বিকল্প। আপনি যদি কেবলমাত্র আর তে আপনার ডেটা পড়তে সক্ষম হন তবে rdsতার চেয়ে ভাল।
রিচি কটন

279

এখানে একটি উদাহরণ যা 1.8.7 freadথেকে ব্যবহার করেdata.table

উদাহরণগুলি সহায়তা পৃষ্ঠা থেকে freadআমার উইন্ডোজ এক্সপি কোর 2 জুটি E8400 এর সময়কালের সাথে আসে।

library(data.table)
# Demo speedup
n=1e6
DT = data.table( a=sample(1:1000,n,replace=TRUE),
                 b=sample(1:1000,n,replace=TRUE),
                 c=rnorm(n),
                 d=sample(c("foo","bar","baz","qux","quux"),n,replace=TRUE),
                 e=rnorm(n),
                 f=sample(1:1000,n,replace=TRUE) )
DT[2,b:=NA_integer_]
DT[4,c:=NA_real_]
DT[3,d:=NA_character_]
DT[5,d:=""]
DT[2,e:=+Inf]
DT[3,e:=-Inf]

স্ট্যান্ডার্ড পঠনযোগ্য

write.table(DT,"test.csv",sep=",",row.names=FALSE,quote=FALSE)
cat("File size (MB):",round(file.info("test.csv")$size/1024^2),"\n")    
## File size (MB): 51 

system.time(DF1 <- read.csv("test.csv",stringsAsFactors=FALSE))        
##    user  system elapsed 
##   24.71    0.15   25.42
# second run will be faster
system.time(DF1 <- read.csv("test.csv",stringsAsFactors=FALSE))        
##    user  system elapsed 
##   17.85    0.07   17.98

অপ্টিমাইজড পঠনযোগ্য

system.time(DF2 <- read.table("test.csv",header=TRUE,sep=",",quote="",  
                          stringsAsFactors=FALSE,comment.char="",nrows=n,                   
                          colClasses=c("integer","integer","numeric",                        
                                       "character","numeric","integer")))


##    user  system elapsed 
##   10.20    0.03   10.32

fread এর

require(data.table)
system.time(DT <- fread("test.csv"))                                  
 ##    user  system elapsed 
##    3.12    0.01    3.22

sqldf

require(sqldf)

system.time(SQLDF <- read.csv.sql("test.csv",dbname=NULL))             

##    user  system elapsed 
##   12.49    0.09   12.69

# sqldf as on SO

f <- file("test.csv")
system.time(SQLf <- sqldf("select * from f", dbname = tempfile(), file.format = list(header = T, row.names = F)))

##    user  system elapsed 
##   10.21    0.47   10.73

এফএফ / এফএফডিএফ

 require(ff)

 system.time(FFDF <- read.csv.ffdf(file="test.csv",nrows=n))   
 ##    user  system elapsed 
 ##   10.85    0.10   10.99

সংক্ষেপে:

##    user  system elapsed  Method
##   24.71    0.15   25.42  read.csv (first time)
##   17.85    0.07   17.98  read.csv (second time)
##   10.20    0.03   10.32  Optimized read.table
##    3.12    0.01    3.22  fread
##   12.49    0.09   12.69  sqldf
##   10.21    0.47   10.73  sqldf on SO
##   10.85    0.10   10.99  ffdf

43
দুর্দান্ত উত্তর, এবং বেঞ্চমার্কিং অন্যান্য বিষয়গুলিতে ধারণ করে। এক মিনিটের সাথে ভালভাবে কেবল 4 জিবি ফাইলে পড়ুন fread। এটি বেস আর ফাংশনগুলির সাথে পড়তে চেষ্টা করেছিল এবং এটি প্রায় 15 ঘন্টা সময় নিয়েছিল।
এরি বি ফ্রেডম্যান

1
আমার মানদণ্ডটি ডেটা.ট্যাবেলে read.csv এর জন্য আরও বেশি গতির সুবিধার প্রস্তাব দেয়। নোট করুন যে ডেটা.ট্যাবিলটি স্ট্যান্ডার্ড আর নয়, তবে (দুঃখের সাথে) "স্রেফ" সুন্দরভাবে তার নির্মাতারা সিআরএএন-তে ভাগ করেছেন। সাধারণ আর প্যাকেজ তালিকা তৈরি করার পক্ষে এটি পর্যাপ্ত মানদণ্ডও নয়, ডেটা ফ্রেমের প্রতিস্থাপন হিসাবে খুব কম যোগ্যতা অর্জন করে। এর অনেক সুবিধা রয়েছে, তবে কিছু খুব বিপরীত দিকও রয়েছে। আপনি স্ট্যান্ডার্ড আর ডেটা ফ্রেম বিশ্বে ফিরে যেতে প্যাকেজটির সাথে as.data.frame (fread.csv ("test.csv")) ব্যবহার করতে চাইতে পারেন।
ivo ওয়েলচ

3
@ মিলেল আপনি দয়া করে পুনরায় চালাতে পারেন এবং মেশিনটি অন্তর্ভুক্ত করতে পারেন readr?
জাঙ্গোরেকি

2
দ্বিতীয় @ জাঙ্গোরেকি। এছাড়াও, freadএখন দেওয়া কিছু প্রকৃত প্রতিযোগী রয়েছে, অনুকূলিতকরণ fread- নির্দিষ্টকরণ colClassesইত্যাদির জন্য বেঞ্চমার্ক যুক্ত করতে দরকারী হতে পারে
মাইকেলচিরিকো

1
@ জ্যাঙ্গোরেকজি @ মাইকেলচিরিকো প্রদত্ত কোডটি সম্পূর্ণরূপে পুনরুত্পাদনযোগ্য তাই এটি পাঠকের অনুকরণের জন্য সরাসরি এগিয়ে রয়েছে ... কোডটি পুনরায় চালু করা, আমার মেশিনে অতিবাহিত সময় দ্বিগুণ দ্রুত হয় যদি বেশিরভাগ ফলাফলের জন্য না হয় তবে আমি এটি নেটওয়ার্কের মাধ্যমে চালিয়ে যাচ্ছি (এবং এটি এখন কিছুটা সময়ের মতো আপডেট হয়েছে! ... এবং পাঠকের সাথে আমি s-এর দশকে আছি তবে যখন আমি দ্বিতীয়বার (0.66s) চালাচ্ছি তখন আমার সন্দেহ হয় যে নেটওয়ার্কে কিছু ক্যাচিং বা বোতল ঘাড় রয়েছে। এখানে দেখানো দ্রুততম সমাধানের জন্য ফ্রিড আমার তুলনায় 2 সেকেন্ডে রয়েছে (প্রথমবারে 8.69s এ চলমান) কোনও কারণে ধীর হয়ে যায়
আর। প্রোস্ট

249

আমি প্রথমে এই প্রশ্নটি দেখতে পেলাম না এবং কয়েকদিন পরে অনুরূপ প্রশ্ন জিজ্ঞাসা করেছি। আমি আমার আগের প্রশ্নটি নীচে নেব, তবে আমি ভেবেছিলাম যে আমি কীভাবে এটি করতাম তা ব্যাখ্যা করার sqldf()জন্য আমি এখানে একটি উত্তর যুক্ত করব।

কোনও আর ডি ফ্রেমে 2 জিবি বা আরও বেশি পাঠ্য ডেটা আমদানির সর্বোত্তম উপায় হিসাবে কিছুটা আলোচনা হয়েছে । গতকাল আমি একটি স্টেজেজ অঞ্চল হিসাবে এসকিউএলাইটে ডেটা আমদানি করার বিষয়ে একটি ব্লগ পোস্ট লিখেছিলাম sqldf()এবং তারপরে এসকিউএলাইট থেকে এটি আরকে চুষেছিলাম This এটি আমার পক্ষে সত্যিই ভাল কাজ করে। আমি <5 মিনিটের মধ্যে 2GB (3 কলাম, 40 মিমি সারি) ডেটা টেনে নিতে সক্ষম হয়েছি। বিপরীতে, read.csvকমান্ডটি সারা রাত চালিয়েছিল এবং কখনও শেষ হয়নি।

আমার পরীক্ষার কোডটি এখানে:

পরীক্ষার ডেটা সেট আপ করুন:

bigdf <- data.frame(dim=sample(letters, replace=T, 4e7), fact1=rnorm(4e7), fact2=rnorm(4e7, 20, 50))
write.csv(bigdf, 'bigdf.csv', quote = F)

নিম্নলিখিত আমদানি রুটিন চালানোর আগে আমি আর পুনরায় চালু করেছি:

library(sqldf)
f <- file("bigdf.csv")
system.time(bigdf <- sqldf("select * from f", dbname = tempfile(), file.format = list(header = T, row.names = F)))

আমি নিম্নলিখিত লাইনটি সারা রাত চালাতে দিয়েছি তবে এটি কখনই শেষ হয়নি:

system.time(big.df <- read.csv('bigdf.csv'))

1
ওহে. সমস্ত ডেটা একসাথে ব্যবহার করার জন্য ডিজাইন করা চিড়িয়াখানা যেমন অন্য প্যাকেজগুলির ইনপুট হিসাবে আপনি কীভাবে ব্যবহার করবেন?
স্ক্যান

@ স্ক্যান শেষ অবজেক্টটি একটি ডেটা ফ্রেম। তাই চিড়িয়াখানার সাথে এটি ব্যবহার করার জন্য আপনাকে এটিকে একটি চিড়িয়াখানাতে রূপান্তর করতে হবে। চিত্রের জন্য চিড়িয়াখানার ডক্সের উদাহরণগুলি দেখুন।
জেডি লং

@ জেডি লং হাই, সমস্যাটি হ'ল আপনি যখন এটিকে চিড়িয়াখানায় কোনও বস্তুতে রূপান্তর করেন এটি এটিকে মেমরির সাথে ফিট করার চেষ্টা করে। যদি এটি খুব বড় হয় তবে এটি একটি ত্রুটি তৈরি করে। এবং যদি চিড়িয়াখানার অবজেক্টের ফলাফল (উদাহরণস্বরূপ দুটি সিরিজের সংমিশ্রণ) খুব বেশি হয় তবে এটির জন্যও একটি স্ক্যল বা এফএফ অবজেক্ট হওয়া দরকার।
স্ক্যান

স্ক্যালডিএফ-এ কী সমস্যা আছে তা আমি জানি না। আমি ডিস্কে একটি সাধারণ 1 জিবি ফাইল তৈরি করেছি (2 টি সংখ্যাযুক্ত কলাম সহ) এবং ডিটিএসকিউএল <- read.csv.sql ("f2.txt", dbname = টেম্পাইল ()) ব্যবহার করেছি এবং এটি মেমরিতে পুরো ডেটা লোড করার চেষ্টা করে। আগামীকাল আমি এর পরিবর্তে এফএফ এবং রেভোস্কেলার চেষ্টা করব।
স্ক্যান

1
@ কি মি হাজার তাই মিমি হাজার হাজার, বা মিলিয়ন। আমার সম্ভবত এটি এমএম হিসাবে মূলধন করা উচিত ছিল। তবে আমি দেখতে পেয়েছি যে আপনার কাছে যদি যথেষ্ট পরিমাণে শ্রোতা থাকে তবে প্রায় কোনও মিলিয়ন সংক্ষিপ্ত বিবরণ কারও কাছে বিভ্রান্ত হতে পারে। অত্যধিক ভার্বোস হওয়ার প্রয়াসে আমি দুঃখিত যে আমি এটিকে আরও বিভ্রান্তিকর করেছিলাম! অ্যাকাউন্টিংকোচ.কম / ব্লগ
জেডি লং

73

আশ্চর্যের বিষয় হল, বছরের পর বছর ধরে কেউ প্রশ্নের নীচের অংশের উত্তর দেয়নি যদিও এটি একটি গুরুত্বপূর্ণ বিষয় হ'ল data.frameসঠিক বৈশিষ্ট্যযুক্ত তালিকাগুলি কেবল তাই আপনার কাছে যদি বড় ডেটা থাকে তবে আপনি as.data.frameকোনও তালিকার জন্য ব্যবহার করতে বা অনুরূপ করতে চান না । কেবলমাত্র স্থানটিকে একটি ডাটা ফ্রেমে একটি তালিকা "চালু" করা খুব দ্রুত:

attr(df, "row.names") <- .set_row_names(length(df[[1]]))
class(df) <- "data.frame"

এটি ডেটার কোনও অনুলিপি তৈরি করে না তাই এটি তাত্ক্ষণিকভাবে (অন্যান্য সমস্ত পদ্ধতির বিপরীতে)। এটি ধরে নেওয়া হয় যে আপনি ইতিমধ্যে names()সেই অনুযায়ী তালিকাতে সেট করেছেন।

[আর-তে বড় ডেটা লোড করার ক্ষেত্রে - ব্যক্তিগতভাবে আমি কলাম দ্বারা এগুলিকে বাইনারি ফাইলগুলিতে ফেলে দিই এবং ব্যবহার করি readBin()- এটি এখন পর্যন্ত দ্রুততম পদ্ধতি (এমএম্যাপিং ব্যতীত) এবং কেবলমাত্র ডিস্কের গতি দ্বারা সীমাবদ্ধ। বাইনারি তথ্যের তুলনায় এএসসিআইআই ফাইলগুলি পার্সিং করা সহজাতভাবে ধীর (এমনকি সিতেও)]


6
ব্যবহারের tracmemপরামর্শ দেয় attr<-এবং class<-অভ্যন্তরীণভাবে অনুলিপিগুলি তৈরি করে। bit::setattrবা data.table::setattrনা।
মিনে

6
আপনি কি ভুল অর্ডার ব্যবহার করেছেন? আপনি যদি ব্যবহার করেন তবে কোনও অনুলিপি নেই df=scan(...); names(df)=...; attr...; class...- দেখুন tracemem()(আর্ট 2.15.2 এ পরীক্ষিত)
সাইমন আরবানেক

3
আপনি কীভাবে বৃহত্তর ডেটাটিকে কলাম দ্বারা বাইনারি ফাইলগুলিতে ডাম্প করতে পারেন তা বিশদভাবে বলতে পারেন?
দাবসিংহ

32

এটি পূর্বে আর- সহায়তায় জিজ্ঞাসা করা হয়েছিল , তাই এটি পর্যালোচনা করার মতো।

এক পরামর্শ সেখানে ব্যবহার করতে ছিল readChar()এবং তারপর সঙ্গে ফলাফলে স্ট্রিং ম্যানিপুলেশন না strsplit()এবং substr()। আপনি দেখতে পারেন রিডচারের সাথে যুক্তি যুক্ত involved

আমি জানি না এখানে মেমোরিটি কোনও সমস্যা কিনা তবে আপনি হ্যাডোপস্ট্রিমিং প্যাকেজটি একবার দেখে নিতে পারেন । এটি হ্যাডোপ ব্যবহার করে , যা বড় ডেটা সেটগুলির সাথে কাজ করার জন্য নকশাকৃত মানচিত্রের ফ্রেমওয়ার্ক। এর জন্য, আপনি hsTableReader ফাংশনটি ব্যবহার করবেন। এটি একটি উদাহরণ (তবে এটি হ্যাডোপ শিখতে শেখার বক্ররেখা রয়েছে):

str <- "key1\t3.9\nkey1\t8.9\nkey1\t1.2\nkey1\t3.9\nkey1\t8.9\nkey1\t1.2\nkey2\t9.9\nkey2\"
cat(str)
cols = list(key='',val=0)
con <- textConnection(str, open = "r")
hsTableReader(con,cols,chunkSize=6,FUN=print,ignoreKey=TRUE)
close(con)

এখানে মূল ধারণাটি হ'ল খণ্ডগুলিতে ডেটা আমদানি ভাঙা। এমনকি আপনি সমান্তরাল ফ্রেমওয়ার্কগুলির একটি (যেমন তুষার) ব্যবহার করতে এবং ফাইলটিকে বিভাগে সমান্তরালভাবে ডেটা আমদানি চালানোর জন্য এতদূর যেতে পেরেছিলেন, তবে সম্ভবত বড় আকারের ডেটা সেটগুলির পক্ষে কার্যকর হবে না যেহেতু আপনি মেমরির সীমাবদ্ধতায় চলে যাবেন, যে কারণে মানচিত্র হ্রাস একটি আরও ভাল পদ্ধতির।


আমি কেবল একটি দ্রুত পরীক্ষা করেছি এবং রিডচার কিছু অনাবশ্যক কারণে রিডলাইনগুলির চেয়ে অনেক দ্রুত বলে মনে হচ্ছে। তবে এটি একটি সাধারণ সি পরীক্ষার তুলনায় পাপ হিসাবে এখনও ধীর। 100 মেগ পড়ার সহজ টাস্কে, আর প্রায় 5 - 10x সি এর চেয়ে ধীরে ধীরে
জোনাথন চ্যাং

1
আপনার কথা বুঝতে পারছেন না। হাদুপের মূল বিষয়টি হ'ল খুব বড় ডেটা হ্যান্ডেল করা যা প্রশ্নটিই ছিল।
শেন

1
নাম সত্ত্বেও, hsTableReader এর প্রতি হ্যাডোপের সাথে কোনও সম্পর্ক নেই, এটি বৃহত ডেটা টুকরো টুকরো করার জন্য। এটি কন থেকে পড়ে, একসাথে সারিগুলির একটি অংশ, এবং প্রতিটি অংশকে ডেটা হিসাবে প্রেরণ করে processing প্রক্রিয়াজাতকরণের জন্য FUN এ ফ্রেম করে। অগ্রাহ্যকি = মিথ্যা দিয়ে, এটি কী (প্রথম কলামে এন্ট্রি) দ্বারা কিছু অতিরিক্ত গ্রুপিং করে যা মানচিত্র / হ্রাস পদ্ধতির সাথে প্রাসঙ্গিক।
ডেভিডআর

ওহে. আপনি কীভাবে এই হ্যাডোপ ডেটাটিকে অন্যান্য প্যাকেজগুলির যেমন ইনপুট হিসাবে একসাথে সমস্ত ডেটা ব্যবহার করার জন্য ডিজাইন করেছিলেন তা ব্যবহার করবেন?
স্ক্যান

10

বিকল্প vroomপ্যাকেজ ব্যবহার করা হয় । এখন CRAN এ। vroomপুরো ফাইলটি লোড করে না, এটি প্রতিটি রেকর্ড যেখানে অবস্থিত তা সূচক করে এবং আপনি এটি ব্যবহার করার পরে পরে পড়তে হবে।

আপনি যা ব্যবহার করেন তার জন্য কেবল অর্থ প্রদান করুন।

বরের পরিচিতি দেখুন , ভ্রুম এবং ভোর মানদণ্ডের সাহায্যে শুরু করুন

প্রাথমিক ওভারভিউটি হ'ল বিশাল ফাইলটির প্রাথমিক পড়া, আরও দ্রুত হবে এবং পরবর্তী সময়ে ডেটাগুলিতে পরিবর্তনগুলি কিছুটা ধীর হতে পারে। সুতরাং আপনার ব্যবহারের উপর নির্ভর করে এটি সর্বোত্তম বিকল্প হতে পারে।

নীচে ভ্রূম বেনমার্ক থেকে একটি সরলীকৃত উদাহরণ দেখুন, দেখার জন্য মূল অংশগুলি হ'ল অতি দ্রুত পঠনযোগ্য সময়, তবে সামান্য বপনকারী ক্রিয়াকলাপ যেমন সামগ্রিক ইত্যাদি ..

package                 read    print   sample   filter  aggregate   total
read.delim              1m      21.5s   1ms      315ms   764ms       1m 22.6s
readr                   33.1s   90ms    2ms      202ms   825ms       34.2s
data.table              15.7s   13ms    1ms      129ms   394ms       16.3s
vroom (altrep) dplyr    1.7s    89ms    1.7s     1.3s    1.9s        6.7s

5

একটি ছোটখাটো অতিরিক্ত বিষয় উল্লেখযোগ্য আপনার যদি খুব বড় ফাইল থাকে তবে আপনি ফ্লাইতে সারিগুলির সংখ্যা গণনা করতে পারেন (যদি শিরোনাম না থাকে) ব্যবহার করে ( bedGraphআপনার কার্যনির্বাহী ডিরেক্টরিতে আপনার ফাইলের নাম কোথায় ):

>numRow=as.integer(system(paste("wc -l", bedGraph, "| sed 's/[^0-9.]*\\([0-9.]*\\).*/\\1/'"), intern=T))

এরপরে আপনি এটি ব্যবহার করতে পারেন read.csv, read.table...

>system.time((BG=read.table(bedGraph, nrows=numRow, col.names=c('chr', 'start', 'end', 'score'),colClasses=c('character', rep('integer',3)))))
   user  system elapsed 
 25.877   0.887  26.752 
>object.size(BG)
203949432 bytes

4

প্রায়শই আমি মনে করি কোনও ডাটাবেসের মধ্যে বৃহত্তর ডাটাবেসগুলি রাখা (উদাহরণস্বরূপ পোস্টগ্রিস) কেবল ভাল অনুশীলন। আমি (নরো * এনসিএল) এনসেল = 10 এম এর চেয়ে বড় কিছু ব্যবহার করি না, যা খুব ছোট; তবে আমি প্রায়শই দেখতে পাই যে আমি একাধিক ডাটাবেস থেকে জিজ্ঞাসা করার সময় কেবল মেমরি নিবিড় গ্রাফ তৈরি করতে এবং ধরে রাখতে চাই। 32 জিবি ল্যাপটপের ভবিষ্যতে, এই ধরণের কিছু মেমরির সমস্যা অদৃশ্য হয়ে যাবে। তবে ডেটা ধরে রাখতে একটি ডাটাবেস ব্যবহার করার প্রবণতা এবং তারপরে ফলাফলের অনুসন্ধানের ফলাফল এবং গ্রাফগুলির জন্য আর এর মেমরি ব্যবহার করা কার্যকর হতে পারে। কিছু সুবিধা হ'ল:

(1) ডেটা আপনার ডাটাবেজে লোড থাকে। আপনি যখন ল্যাপটপটি আবার চালু করেন তখন আপনি পিগডমিনে আপনার যে ডাটাবেসগুলি চান তা কেবল পুনরায় সংযোগ স্থাপন করেন।

(২) এটি সত্য যে এস এসকিউএল এর চেয়ে অনেক বেশি নিফটি পরিসংখ্যান এবং গ্রাফিং অপারেশন করতে পারে। তবে আমি মনে করি এসকিউএল আর এর চেয়ে বেশি পরিমাণে ডেটা অনুসন্ধানের জন্য আরও ভালভাবে ডিজাইন করা হয়েছে I

# Looking at Voter/Registrant Age by Decade

library(RPostgreSQL);library(lattice)

con <- dbConnect(PostgreSQL(), user= "postgres", password="password",
                 port="2345", host="localhost", dbname="WC2014_08_01_2014")

Decade_BD_1980_42 <- dbGetQuery(con,"Select PrecinctID,Count(PrecinctID),extract(DECADE from Birthdate) from voterdb where extract(DECADE from Birthdate)::numeric > 198 and PrecinctID in (Select * from LD42) Group By PrecinctID,date_part Order by Count DESC;")

Decade_RD_1980_42 <- dbGetQuery(con,"Select PrecinctID,Count(PrecinctID),extract(DECADE from RegistrationDate) from voterdb where extract(DECADE from RegistrationDate)::numeric > 198 and PrecinctID in (Select * from LD42) Group By PrecinctID,date_part Order by Count DESC;")

with(Decade_BD_1980_42,(barchart(~count | as.factor(precinctid))));
mtext("42LD Birthdays later than 1980 by Precinct",side=1,line=0)

with(Decade_RD_1980_42,(barchart(~count | as.factor(precinctid))));
mtext("42LD Registration Dates later than 1980 by Precinct",side=1,line=0)

3

আমি নতুন arrowপ্যাকেজটি ব্যবহার করে খুব দ্রুত ডেটা পড়ছি । এটি মোটামুটি প্রাথমিক পর্যায়ে উপস্থিত রয়েছে।

বিশেষত, আমি parquet কলামার ফর্ম্যাট ব্যবহার করছি । এটি data.frameআর- তে ফিরে আসে , তবে আপনি যদি না করেন তবে আরও গভীর স্পিডআপগুলি পেতে পারেন। এই ফর্ম্যাটটি সুবিধাজনক কারণ এটি পাইথন থেকেও ব্যবহার করা যেতে পারে।

এর জন্য আমার প্রধান ব্যবহারের ক্ষেত্রেটি মোটামুটি সংযত আরএসআইইন সার্ভারে। এই কারণে, আমি অ্যাপ্লিকেশনগুলিতে ডেটা সংযুক্ত রাখতে পছন্দ করি (অর্থাত্ এসকিউএল এর বাইরে), এবং সেইজন্য ছোট ফাইলের আকারের পাশাপাশি গতিও প্রয়োজন।

এই লিঙ্কযুক্ত নিবন্ধটি মানদণ্ড এবং একটি ভাল ওভারভিউ সরবরাহ করে। আমি নীচে কিছু আকর্ষণীয় পয়েন্ট উদ্ধৃত করেছি।

https://ursalabs.org/blog/2019-10-columnar-perf/

ফাইলের আকার

অর্থাৎ পারকুইট ফাইলটি জিপিড সিএসভি এমনকি অর্ধেক বড়। পারকুইট ফাইলটি এত ছোট হওয়ার একটি কারণ অভিধান-এনকোডিং (এটি "অভিধান সংক্ষেপণ" নামেও পরিচিত)। অভিধান সংক্ষেপণ এলজেড 4 বা জেডএসটিডি (যা এফএসটি ফর্ম্যাটে ব্যবহৃত হয়) এর মতো একটি সাধারণ উদ্দেশ্য বাইট কম্প্রেসর ব্যবহার করার চেয়ে যথেষ্ট উন্নত সংক্ষেপণ পেতে পারে। পরকুইট খুব ছোট ফাইলগুলি পড়ার জন্য দ্রুত তৈরি করার জন্য ডিজাইন করা হয়েছিল।

গতি পড়ুন

আউটপুট টাইপ দ্বারা নিয়ন্ত্রণ করার সময় (যেমন সমস্ত আর ডেটা ফ্রেম আউটপুট একে অপরের সাথে তুলনা করে) আমরা পারকুইট, ফেদার এবং এফএসটি এর পারফরম্যান্স একে অপরের অপেক্ষাকৃত ছোট ব্যবধানের মধ্যে দেখতে পাই। প্যান্ডাসের ক্ষেত্রেও একই কথা রয়েছে ata ডেটা ফ্রেমের আউটপুট। ডেটা.টিবেল :: ফ্রেড 1.5 গিগাবাইট ফাইলের আকারের সাথে চিত্তাকর্ষকভাবে প্রতিযোগিতামূলক তবে 2.5 জিবি সিএসভিতে অন্যকে পিছনে ফেলেছে।


স্বতন্ত্র পরীক্ষা

আমি 1,000,000 সারিগুলির সিমুলেটেড ডেটাসেটে কিছু স্বতন্ত্র বেঞ্চমার্কিং করেছি king মূলত আমি কম্প্রেশনকে চ্যালেঞ্জ করার চেষ্টা করার জন্য প্রচুর জিনিসগুলিকে বদলেছি। এছাড়াও আমি এলোমেলো শব্দের একটি সংক্ষিপ্ত পাঠ্য ক্ষেত্র এবং দুটি সিমুলেটেড কারণ যুক্ত করেছি।

উপাত্ত

library(dplyr)
library(tibble)
library(OpenRepGrid)

n <- 1000000

set.seed(1234)
some_levels1 <- sapply(1:10, function(x) paste(LETTERS[sample(1:26, size = sample(3:8, 1), replace = TRUE)], collapse = ""))
some_levels2 <- sapply(1:65, function(x) paste(LETTERS[sample(1:26, size = sample(5:16, 1), replace = TRUE)], collapse = ""))


test_data <- mtcars %>%
  rownames_to_column() %>%
  sample_n(n, replace = TRUE) %>%
  mutate_all(~ sample(., length(.))) %>%
  mutate(factor1 = sample(some_levels1, n, replace = TRUE),
         factor2 = sample(some_levels2, n, replace = TRUE),
         text = randomSentences(n, sample(3:8, n, replace = TRUE))
         )

পড় ও লিখ

ডেটা লেখা সহজ।

library(arrow)

write_parquet(test_data , "test_data.parquet")

# you can also mess with the compression
write_parquet(test_data, "test_data2.parquet", compress = "gzip", compression_level = 9)

ডেটা পড়াও সহজ।

read_parquet("test_data.parquet")

# this option will result in lightning fast reads, but in a different format.
read_parquet("test_data2.parquet", as_data_frame = FALSE)

আমি প্রতিযোগী কয়েকটি বিকল্পের বিরুদ্ধে এই তথ্যটি পরীক্ষা করে দেখেছি এবং উপরের নিবন্ধটির চেয়ে কিছুটা আলাদা ফলাফল পেয়েছি, যা প্রত্যাশিত।

মাপকাঠিতে

এই ফাইলটি বেঞ্চমার্ক নিবন্ধের মতো বৃহত্তর আর কোথাও নেই, সুতরাং এটির পার্থক্যও সম্ভবত।

টেস্ট

  • আরডিএস: test_data.rds (20.3 এমবি)
  • parquet2_native: (উচ্চ সংকোচনের সাথে 14.9 এমবি এবং as_data_frame = FALSE)
  • parquet2: test_data2.parquet (উচ্চ সংকোচনের সাথে 14.9 মেগাবাইট)
  • parquet: test_data.parquet (40.7 এমবি)
  • fst2: test_data2.fst (উচ্চ সংকোচনের সাথে ২ 27.৯ এমবি)
  • fst: test_data.fst ( .8 MB.৮ এমবি)
  • fread2: test_data.csv.gz (23.6MB)
  • ফ্রেড : টেস্ট_ডাটা সিএসভি (98.7MB)
  • ফেদার_আরো : টেস্ট_ডেটা.ফ্যাথার (157.2 এমবি সহ পড়ুন arrow)
  • পালক: test_data.feather (157.2 মেগাবাইট সহ পড়া feather)

পর্যবেক্ষণ

এই নির্দিষ্ট ফাইলের জন্য, freadআসলে খুব দ্রুত। আমি অত্যন্ত সঙ্কুচিত parquet2পরীক্ষা থেকে ছোট ফাইল আকার পছন্দ করি । আমার data.frameসত্যিকারের গতি বাড়ানোর প্রয়োজনে আমি দেশী ডেটা ফর্ম্যাটটির সাথে কাজ করার জন্য সময়টি বিনিয়োগ করতে পারি।

এখানেও fstদুর্দান্ত পছন্দ। যদি হয় আমার গতি বা ফাইলের আকারের বাণিজ্য বন্ধ হওয়ার প্রয়োজন হয় তার উপর নির্ভর করে আমি অত্যন্ত সঙ্কুচিত fstফর্ম্যাট বা উচ্চ সংক্ষেপিত ব্যবহার parquetকরব।


0

প্রচলিত পড়ার পরিবর্তে আমার মনে হয় ফ্রিড একটি দ্রুত কাজ। অতিরিক্ত বৈশিষ্ট্য নির্দিষ্টকরণের মতো কেবল প্রয়োজনীয় কলামগুলি নির্বাচন করুন, শ্রেণি শ্রেণি এবং স্ট্রিংকে কারণ হিসাবে নির্দিষ্ট করে ফাইলটি আমদানি করতে সময় কমবে।

data_frame <- fread("filename.csv",sep=",",header=FALSE,stringsAsFactors=FALSE,select=c(1,4,5,6,7),colClasses=c("as.numeric","as.character","as.numeric","as.Date","as.Factor"))

0

আমি সর্বোপরি চেষ্টা করেছি এবং [পাঠক] [1] সেরা কাজ করেছেন। আমার কাছে মাত্র 8 জিবি র‌্যাম রয়েছে

20 টি ফাইলের জন্য লুপ, প্রতিটি 5 জিবি, 7 টি কলাম:

read_fwf(arquivos[i],col_types = "ccccccc",fwf_cols(cnpj = c(4,17), nome = c(19,168), cpf = c(169,183), fantasia = c(169,223), sit.cadastral = c(224,225), dt.sitcadastral = c(226,233), cnae = c(376,382)))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.