একটি দ্রুত এবং সুসংহত tidyverse
সমাধান: ( বেস আর এর চেয়ে দ্বিগুণের বেশি দ্রুত read.csv
)
tbl <-
list.files(pattern = "*.csv") %>%
map_df(~read_csv(.))
এবং ডেটা.ট্যাবস এর fread()
এমনকি লোডের সময়গুলি অর্ধেক করে কেটে ফেলতে পারে। ( বেস আর বারের 1/4 বারের জন্য)
library(data.table)
tbl_fread <-
list.files(pattern = "*.csv") %>%
map_df(~fread(.))
stringsAsFactors = FALSE
যুক্তি dataframe ফ্যাক্টর বিনামূল্যে রাখে, (এবং marbel পয়েন্ট আউট হিসাবে, ডিফল্ট সেটিং fread
)
যদি টাইপকাস্টিংটি চটকদার হয়ে থাকে তবে আপনি সমস্ত কলামকে col_types
যুক্তির সাথে অক্ষর হিসাবে বাধ্য করতে পারেন ।
tbl <-
list.files(pattern = "*.csv") %>%
map_df(~read_csv(., col_types = cols(.default = "c")))
যদি আপনি আপনার ফাইলগুলির তালিকাটি শেষ পর্যন্ত বাঁধাই করতে সাবডাইরেক্টরিগুলিতে ডুবতে চান তবে অবশ্যই সেই পথের নাম অন্তর্ভুক্ত করার পাশাপাশি আপনার তালিকায় তাদের সম্পূর্ণ নাম সহ ফাইলগুলি নিবন্ধভুক্ত করতে ভুলবেন না। এটি বাধ্যতামূলক কাজটিকে বর্তমান ডিরেক্টরিটির বাইরের দিকে যেতে দেয়। (পুরো পথের নামগুলি পাসপোর্টের মতো চালনা হিসাবে ডিরেক্টরি 'সীমানা' জুড়ে চলাচলের অনুমতি দেওয়ার জন্য চিন্তা করা))
tbl <-
list.files(path = "./subdirectory/",
pattern = "*.csv",
full.names = T) %>%
map_df(~read_csv(., col_types = cols(.default = "c")))
যেমন হ্যাডলি এখানে বর্ণনা করেছেন (প্রায় অর্ধেক নীচে):
map_df(x, f)
কার্যকরভাবে একই do.call("rbind", lapply(x, f))
....
বোনাস বৈশিষ্ট্য - নীচে মন্তব্যগুলিতে অনুরোধ রেকর্ডে ফাইলের নাম যুক্ত করে:
* filename
প্রতিটি রেকর্ডে আসল যুক্ত করুন ।
কোড ব্যাখ্যা করেছে: টেবিলগুলির প্রাথমিক পাঠের সময় প্রতিটি রেকর্ডে ফাইলের নাম যুক্ত করার জন্য একটি ফাংশন তৈরি করুন। তারপরে সাধারণ ফাংশনের পরিবর্তে সেই ফাংশনটি ব্যবহার করুন read_csv()
।
read_plus <- function(flnm) {
read_csv(flnm) %>%
mutate(filename = flnm)
}
tbl_with_sources <-
list.files(pattern = "*.csv",
full.names = T) %>%
map_df(~read_plus(.))
(টাইপকাস্টিং এবং সাব-ডিরেক্টরী হ্যান্ডলিং পন্থাগুলিও read_plus()
একইভাবে ফাংশনের অভ্যন্তরে পরিচালনা করা যেতে পারে যা উপরে প্রস্তাবিত দ্বিতীয় এবং তৃতীয় রূপগুলিতে চিত্রিত হয়েছে।)
### Benchmark Code & Results
library(tidyverse)
library(data.table)
library(microbenchmark)
### Base R Approaches
#### Instead of a dataframe, this approach creates a list of lists
#### removed from analysis as this alone doubled analysis time reqd
# lapply_read.delim <- function(path, pattern = "*.csv") {
# temp = list.files(path, pattern, full.names = TRUE)
# myfiles = lapply(temp, read.delim)
# }
#### `read.csv()`
do.call_rbind_read.csv <- function(path, pattern = "*.csv") {
files = list.files(path, pattern, full.names = TRUE)
do.call(rbind, lapply(files, function(x) read.csv(x, stringsAsFactors = FALSE)))
}
map_df_read.csv <- function(path, pattern = "*.csv") {
list.files(path, pattern, full.names = TRUE) %>%
map_df(~read.csv(., stringsAsFactors = FALSE))
}
### *dplyr()*
#### `read_csv()`
lapply_read_csv_bind_rows <- function(path, pattern = "*.csv") {
files = list.files(path, pattern, full.names = TRUE)
lapply(files, read_csv) %>% bind_rows()
}
map_df_read_csv <- function(path, pattern = "*.csv") {
list.files(path, pattern, full.names = TRUE) %>%
map_df(~read_csv(., col_types = cols(.default = "c")))
}
### *data.table* / *purrr* hybrid
map_df_fread <- function(path, pattern = "*.csv") {
list.files(path, pattern, full.names = TRUE) %>%
map_df(~fread(.))
}
### *data.table*
rbindlist_fread <- function(path, pattern = "*.csv") {
files = list.files(path, pattern, full.names = TRUE)
rbindlist(lapply(files, function(x) fread(x)))
}
do.call_rbind_fread <- function(path, pattern = "*.csv") {
files = list.files(path, pattern, full.names = TRUE)
do.call(rbind, lapply(files, function(x) fread(x, stringsAsFactors = FALSE)))
}
read_results <- function(dir_size){
microbenchmark(
# lapply_read.delim = lapply_read.delim(dir_size), # too slow to include in benchmarks
do.call_rbind_read.csv = do.call_rbind_read.csv(dir_size),
map_df_read.csv = map_df_read.csv(dir_size),
lapply_read_csv_bind_rows = lapply_read_csv_bind_rows(dir_size),
map_df_read_csv = map_df_read_csv(dir_size),
rbindlist_fread = rbindlist_fread(dir_size),
do.call_rbind_fread = do.call_rbind_fread(dir_size),
map_df_fread = map_df_fread(dir_size),
times = 10L)
}
read_results_lrg_mid_mid <- read_results('./testFolder/500MB_12.5MB_40files')
print(read_results_lrg_mid_mid, digits = 3)
read_results_sml_mic_mny <- read_results('./testFolder/5MB_5KB_1000files/')
read_results_sml_tny_mod <- read_results('./testFolder/5MB_50KB_100files/')
read_results_sml_sml_few <- read_results('./testFolder/5MB_500KB_10files/')
read_results_med_sml_mny <- read_results('./testFolder/50MB_5OKB_1000files')
read_results_med_sml_mod <- read_results('./testFolder/50MB_5OOKB_100files')
read_results_med_med_few <- read_results('./testFolder/50MB_5MB_10files')
read_results_lrg_sml_mny <- read_results('./testFolder/500MB_500KB_1000files')
read_results_lrg_med_mod <- read_results('./testFolder/500MB_5MB_100files')
read_results_lrg_lrg_few <- read_results('./testFolder/500MB_50MB_10files')
read_results_xlg_lrg_mod <- read_results('./testFolder/5000MB_50MB_100files')
print(read_results_sml_mic_mny, digits = 3)
print(read_results_sml_tny_mod, digits = 3)
print(read_results_sml_sml_few, digits = 3)
print(read_results_med_sml_mny, digits = 3)
print(read_results_med_sml_mod, digits = 3)
print(read_results_med_med_few, digits = 3)
print(read_results_lrg_sml_mny, digits = 3)
print(read_results_lrg_med_mod, digits = 3)
print(read_results_lrg_lrg_few, digits = 3)
print(read_results_xlg_lrg_mod, digits = 3)
# display boxplot of my typical use case results & basic machine max load
par(oma = c(0,0,0,0)) # remove overall margins if present
par(mfcol = c(1,1)) # remove grid if present
par(mar = c(12,5,1,1) + 0.1) # to display just a single boxplot with its complete labels
boxplot(read_results_lrg_mid_mid, las = 2, xlab = "", ylab = "Duration (seconds)", main = "40 files @ 12.5MB (500MB)")
boxplot(read_results_xlg_lrg_mod, las = 2, xlab = "", ylab = "Duration (seconds)", main = "100 files @ 50MB (5GB)")
# generate 3x3 grid boxplots
par(oma = c(12,1,1,1)) # margins for the whole 3 x 3 grid plot
par(mfcol = c(3,3)) # create grid (filling down each column)
par(mar = c(1,4,2,1)) # margins for the individual plots in 3 x 3 grid
boxplot(read_results_sml_mic_mny, las = 2, xlab = "", ylab = "Duration (seconds)", main = "1000 files @ 5KB (5MB)", xaxt = 'n')
boxplot(read_results_sml_tny_mod, las = 2, xlab = "", ylab = "Duration (milliseconds)", main = "100 files @ 50KB (5MB)", xaxt = 'n')
boxplot(read_results_sml_sml_few, las = 2, xlab = "", ylab = "Duration (milliseconds)", main = "10 files @ 500KB (5MB)",)
boxplot(read_results_med_sml_mny, las = 2, xlab = "", ylab = "Duration (microseconds) ", main = "1000 files @ 50KB (50MB)", xaxt = 'n')
boxplot(read_results_med_sml_mod, las = 2, xlab = "", ylab = "Duration (microseconds)", main = "100 files @ 500KB (50MB)", xaxt = 'n')
boxplot(read_results_med_med_few, las = 2, xlab = "", ylab = "Duration (seconds)", main = "10 files @ 5MB (50MB)")
boxplot(read_results_lrg_sml_mny, las = 2, xlab = "", ylab = "Duration (seconds)", main = "1000 files @ 500KB (500MB)", xaxt = 'n')
boxplot(read_results_lrg_med_mod, las = 2, xlab = "", ylab = "Duration (seconds)", main = "100 files @ 5MB (500MB)", xaxt = 'n')
boxplot(read_results_lrg_lrg_few, las = 2, xlab = "", ylab = "Duration (seconds)", main = "10 files @ 50MB (500MB)")
মিডল্লিং ইউজ কেস
বড় ব্যবহারের কেস
ব্যবহারের ক্ষেত্রে বিভিন্ন ধরণের
সারি: ফাইল গণনা (1000, 100, 10)
কলাম: চূড়ান্ত ডেটাফ্রেম আকার (5MB, 50MB, 500MB)
(মূল আকার দেখতে চিত্রটিতে ক্লিক করুন)
বৃহত্তর স্কেল প্রসেসিংয়ের কাজ সম্পাদন করার সময় পরিলক্ষিত পারফরম্যান্সের তুলনায় সিআর লাইব্রেরিগুলি সিআর লাইব্রেরিগুলি আনার ওভারহেডগুলি সবচেয়ে ছোট ব্যবহারের ক্ষেত্রে বেজ আর ফলাফলগুলি আরও ভাল।
আপনি যদি নিজের পরীক্ষা চালাতে চান তবে আপনি এই ব্যাশ স্ক্রিপ্টটিকে সহায়ক বলে মনে করতে পারেন।
for ((i=1; i<=$2; i++)); do
cp "$1" "${1:0:8}_${i}.csv";
done
bash what_you_name_this_script.sh "fileName_you_want_copied" 100
ক্রম অনুসারে আপনার ফাইলের 100 টি অনুলিপি তৈরি করবে (ফাইলের প্রাথমিক 8 টি অক্ষর এবং একটি আন্ডারস্কোরের পরে)।
গুণাবলী এবং প্রশংসা
বিশেষ ধন্যবাদ সাথে:
- টাইলার রিঙ্কার এবং আকরুন প্রদর্শনের জন্য আকরুন।
- আমাকে এখানে পরিচয় করানোর জন্য জ্যাক কাউপ
map_df()
।
- ডেভিড ম্যাকলফলিন ভিজ্যুয়ালাইজেশনের উন্নতি এবং ছোট ফাইল, ছোট ডেটাফ্রেম বিশ্লেষণ ফলাফলের মধ্যে পরিলক্ষিত পারফরম্যান্স উল্টোপাল্টা নিয়ে আলোচনা / নিশ্চিত করার বিষয়ে সহায়ক প্রতিক্রিয়ার জন্য।
- জন্য ডিফল্ট আচরণ নির্দেশ করে জন্য মার্বেল
fread()
। (আমি পড়াশোনা করা প্রয়োজন data.table
।)