Объедините несколько файлов CSV в ... с максимальным ограничением размера

1

Я ищу решение R или решение Python для объединения нескольких тысяч файлов CSV в несколько больших файлов с ограничением по размеру 1 ГБ. У меня есть несколько сценариев, которые объединяют все файлы CSV в папке в один CSV файл, но этот файл, вероятно, будет слишком большим для работы, поэтому я хотел бы объединиться, как 10, 11, 12, файлы или что-то еще, до 1 ГБ, сохранить этот файл, а затем начать слияние нескольких оставшихся файлов во второй CSV около 1 ГБ, за исключением этого и т.д. и т.д. Некоторое время я искал язык и не мог найти решения для этого. Если бы кто-нибудь здесь мог помочь, я был бы очень признателен. TIA !!

Мой код для объединения нескольких файлов CV в один файл выглядит так. Очевидно, что существует несколько способов сделать практически одно и то же, поэтому я уверен, что в основном есть похожие, но немного разные способы сделать такие вещи.

Я думаю, что код будет выглядеть примерно так, основываясь на комментариях Shree ниже.

setwd("C:/Users/ryans/OneDrive/Desktop/test")

# assuming all files are in working directory
files <- list.files(pattern = ".csv")

file_sizes <- sapply(files, function(x) file.size(x)) # sizes in bytes
cum_sizes <- cumsum(file_sizes)

file_read_groups <- cut(cum_sizes, breaks = seq(0, max(cum_sizes), by = min(500000, max(cum_sizes))))

# code to read and combine CSV from each file group which you already have
txt_files <- list.files()
list_of_reads <- lapply(files, readLines)

for(i in 1:length(list_of_reads)){
    df_of_reads <- data.frame(file_name = txt_files, contents = do.call(rbind, files))
    write.csv(df_of_reads, "csv" + toString(i) + ".csv", row.names = F)
    next
  }

Однако этот скрипт вызывает это сообщение об ошибке.

Error in do.call(rbind, files) : second argument must be a list

Я думал, что вторым аргументом был список...

  • 0
    в R вы можете попробовать использовать file.size() чтобы получить размеры всех ваших файлов в каталоге, а затем сгруппировать и прочитать их так, чтобы размер каждой группы был <= 1 ГБ.
  • 0
    Альтернативное решение состоит в том, чтобы объединить все CSV и сохранить их в базе данных, такой как sqlite, R имеет хороший интерфейс для этого .
Теги:
python-3.x

2 ответа

1
Лучший ответ

Подумайте о создании фрейма данных ваших файлов и метаданных. Затем запустите by чтения файлов и сохранять по группам. Ниже не гарантируются файлы одинакового размера, но выводятся файлы CSV в блоках размером 1 ГБ.

files <- list.files(pattern = ".csv")                 # csvs in work directory    
file_sizes <- file.size(files)                        # sizes in bytes (no sapply needed)
cum_sizes <- cumsum(file_sizes)                       # cumulative bytes
file_read_groups <- as.integer(cum_sizes / 1e9)       # floor multiples of 1 GB

# FILE DATA FRAME BUILD
files_df <- data.frame(files, file_sizes, cum_sizes, file_read_groups, 
                       row.names = NULL, stringsAsFactors = FALSE)

# PROCESS BY GROUP   
output <- by(files_df, files_df$file_read_groups, function(sub) {                  
    # READ CSVs AND BIND IN ONE DATA FILES
    tmp <- do.call(rbind, lapply(sub$files, read.csv))

    # EXPORT FILE TO DISK
    write.csv(tmp, paste0(sub$file_read_groups[[1]], ".csv"), row.names = FALSE)  
})
  • 0
    Привет. Это похоже на правильный подход, Parfait, но когда я запускаю этот код, я получаю следующую ошибку: Ошибка в read.table (file = file, header = header, sep = sep, quote = quote,: 'file' должен быть строка символов или соединение Все, вплоть до 'files_df', работает нормально. Однако сохранение по группам не работает. Есть идеи, что здесь может быть не так?
  • 1
    Попробуйте добавить stringsAsFactors = FALSE в data.frame() поскольку файлы хранятся как факторы.
Показать ещё 4 комментария
0

Следуя за моим комментарием, что-то вроде этого должно получиться -

# assuming all files are in working directory
files <- list.files(pattern = ".csv")
file_sizes <- sapply(files, function(x) file.size(x)) # sizes in bytes
cum_sizes <- cumsum(file_sizes)
file_read_groups <- cut(cum_sizes, breaks = seq(0, max(cum_sizes), by = min(1e9, max(cum_sizes))))
# code to read and combine CSV from each file group which you already have
  • 0
    Благодарю. Это определенно выглядит многообещающе. Мне интересно, как включить ваш код в мой собственный код. Я не вижу очевидного способа сделать это. Благодарю.
  • 0
    Я изменил код в своем исходном сообщении, основываясь на ваших предложениях. Теперь я получаю новую ошибку. Вы видите это? Вы знаете, что происходит? Благодарю.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню