ITPub博客

首页 > > > R语言并行读取csv:地表最快csv合并方法

R语言并行读取csv:地表最快csv合并方法

作者:浪花小雨滴 时间:2020-01-07 19:19:19 0 删除 编辑

作者:黄天元,复旦大学博士在读,热爱数据科学与开源工具(R),致力于利用数据科学迅速积累行业经验优势和科学知识发现,涉猎内容包括但不限于信息计量、机器学习、数据可视化、应用统计建模、知识图谱等,著有《R语言数据高效处理指南》(《R语言数据高效处理指南》(黄天元)【摘要 书评 试读】- 京东图书,《R语言数据高效处理指南》(黄天元)【简介_书评_在线阅读】 - 当当图书)。知乎专栏:R语言数据挖掘。邮箱:huang.tian-yuan@qq.com.欢迎合作交流。


以前有多个csv要合并成一个(文件所有的列一般都是一致的),把文件路径设置到那里,然后写一个循环一个一个读,然后每个循环后面就使用rbind/bind_rows合在一起。比如:

library(tidyverse)

# 假设已经在csv文件所在路径

dir() %>% str_subset("\\.csv$") -> fn
all = tibble()
for(i in fn){
 read_csv(i) %>%
   bind_rows(all) -> all
}

为了充分利用计算机的所有性能,让读取更加迅速,我在多次试错下,终于写下这么一段代码:

library(pacman)
p_load(doParallel,data.table,dplyr,stringr,fst)

# 识别所在文件路径下所有的csv文件名称
dir() %>% str_subset("\\.csv$") -> fn

# 并行计算环境设置
(cl = detectCores() %>% 
  makeCluster()) %>% 
  registerDoParallel()

# 并行读取csv,并进行合并
system.time({
  big_df = foreach(i = fn,
                    .packages = "data.table") %dopar% {
                      fread(i,colClasses = "character")
                    } %>% 
    rbindlist(fill = T)
})

# 停止并行环境
stopCluster(cl)

# 读出文件
write_fst(big_df,"big_df.fst",compress = 100)

# fwrite(big_df,"bid_df.csv")

这是我目前探索出来能够最快速度合并任意文件夹任意数量csv的代码,没有之一。计算机的核越多,效果越明显。fread的快速在当前是无可匹敌的,而colClasses参数的设置,让读取不需要进行过多的数据类型判断,这样在最后合并的时候也就不会报错。rbindlist是data.table中专门用来合并列表中data.table的函数,fill设置为TRUE可以提高容错性(如果多个数据表中列名称不同,会填充NA值)。最后,合并成一个巨大的数据框,存在big_df中,建议使用fst包来读出,compress开到尽头设置为100,可以实现最大的压缩和快速读写,空间时间双节省(如果一定需要csv格式的话,也可以用fwrite读出)。我想这样的数据表可能永远也不会需要完全读入,fst支持部分读取功能(读取部分行或列),因此fst这个格式是非常合适的。


2020/04/29更新:新的方案

if (!require("pacman")) install.packages("pacman")
pacman::p_load(future.apply, data.table, stringr)

# get the file name
dir() %>% str_subset("\\.csv$") -> fn

plan(multiprocess)

future_lapply(fn,fread,colClasses = "character") %>% 
  rbindlist(fill = TRUE) -> res

res就是我们要的合并后的数据框。

原文作者:;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2018-05-16

  • 博文量
    4259
  • 访问量
    39977