R 读取大型Excel xlsx文件的最快方法?是否并行化?
我的问题是:R 读取大型Excel xlsx文件的最快方法?是否并行化?,r,parallel-processing,readxl,R,Parallel Processing,Readxl,我的问题是: library(microbenchmark) microbenchmark( lapply = {lapply(sheets, function(sheet) { read_excel(excel_path, sheet = sheet) })}, parralel = {parLapplyLB(cl, sheets, function(sheet, excel_path) { readxl::read_excel(excel_path, sheet
library(microbenchmark)
microbenchmark(
lapply = {lapply(sheets, function(sheet) {
read_excel(excel_path, sheet = sheet)
})},
parralel = {parLapplyLB(cl, sheets, function(sheet, excel_path) {
readxl::read_excel(excel_path, sheet = sheet)
}, excel_path)},
times = 10
)
- 将大型(ish).xlsx Excel文件读入R的最快方法是什么?10到200 MB xlsx文件,包含多张工作表
- 是否可以使用某种并行处理,例如每个磁芯读数 多工作表Excel文件的单独工作表
- 是否有其他类型的优化可以执行
- 如果像我一样从旋转磁盘读取数据,并行处理实际上可能会减慢读取速度,因为多个进程试图从同一个文件读取数据。然而,并行过程可能有助于转换和推断数据类型?不确定readxl从磁盘读取(我假设是IO绑定的)和转换数据类型(我猜是CPU绑定的)的开销
- 这可能与SSD驱动器不同。如果有重大改进,我可能会将数据复制到SSD驱动器并从那里读取数据
- fread可以加快文本文件的读取速度(虽然我不完全理解为什么),但它不能用于excel文件,或者可以
- 我从中了解到,
往往比readxl
openxlsx
readxl
比Python的pandas
快得多(在一张15页的xlsx上,每张有10000行和32列的纸:readxl为5.6秒,pandas为33秒),那太好了!不过,我仍想了解是否有任何方法可以加快进口速度。我可以用R读取文件,将它们导出到SQL,然后用Python从SQL读取继续我的其余工作流程。
我不认为转换为CSV是最好的选择,尤其是在readxl比Python快得多的情况下;基本上,转换为csv可能比我从csv而不是excel中读取所节省的时间要长。另外,至少在Python中(我对R的了解还不足以用readxl对此进行彻底测试),使用xlsx推断数据类型比使用csv好得多
我的代码(欢迎任何批评或建议):
库(readxl)
图书馆(tidyverse)
图书馆(tictoc)
this.dir您可以尝试使用parallel
软件包并行运行它,但是如果没有样本数据,估计它的速度有点困难:
library(parallel)
library(readxl)
excel_path <- ""
sheets <- excel_sheets(excel_path)
您可以使用软件包microbenchmark
测试某些选项的速度:
library(microbenchmark)
microbenchmark(
lapply = {lapply(sheets, function(sheet) {
read_excel(excel_path, sheet = sheet)
})},
parralel = {parLapplyLB(cl, sheets, function(sheet, excel_path) {
readxl::read_excel(excel_path, sheet = sheet)
}, excel_path)},
times = 10
)
在我的例子中,并行版本更快:
Unit: milliseconds
expr min lq mean median uq max neval
lapply 133.44857 167.61801 179.0888 179.84616 194.35048 226.6890 10
parralel 58.94018 64.96452 118.5969 71.42688 80.48588 316.9914 10
测试文件包含6张图纸,每张图纸包含以下表格:
test test1 test3 test4 test5
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
4 4 4 4 4 4
5 5 5 5 5 5
6 6 6 6 6 6
7 7 7 7 7 7
8 8 8 8 8 8
9 9 9 9 9 9
10 10 10 10 10 10
11 11 11 11 11 11
12 12 12 12 12 12
13 13 13 13 13 13
14 14 14 14 14 14
15 15 15 15 15 15
注:
您可以使用stopCluster(cl)
在流程完成时关闭工人。我看到@clemens的回答,但由于我已经准备了一些资料,所以我还是要发布它。除了@clemens answer,我还使用了更大的测试数据,并使用furr::future\u map()
运行了更简单的多核选项,这最终不会带来任何性能提升
数据生成
这将创建10张10000*15数据表,混合使用浮点、整数和字符。在我的磁盘上,文件大小是13.2MB
库(writexl)
图书馆(tidyverse)
找不到合适的复制品。你试过fread吗?!我认为fread只适用于文本文件,而不是xlsx。还是我弄错了?我还注意到,在R中,将相同的58Mbs数据导出到SQL要比在Python中快得多:4.25vs18.4secondsHanks!文件是在SSD上还是在旋转磁盘上?负载平衡做什么?我们为什么需要它?我理解parLapplyLB
进行负载平衡,而parLapply
不进行负载平衡;使用后者会产生关于关闭未使用的连接的警告,但仍会在似乎相同的时间内读取数据。如果您有4个内核,并且希望在8张纸中读取数据,所有这些都需要不同的时间量,则您将开始在4张纸中读取数据,等待所有操作完成,然后转到其他4张。通过负载平衡,进程之间不必互相等待,一个核心将在第一个工作表上工作,而其他核心将继续工作到下一个工作表。非常感谢,您是一个明星!所以在我的例子中,它可能需要相同的时间,因为所有的床单都有相同的尺寸;在其他情况下,负载平衡可能会有所不同。请尝试包括fread
。我发现它非常适合大文件。
Unit: milliseconds
expr min lq mean median uq max neval
lapply 133.44857 167.61801 179.0888 179.84616 194.35048 226.6890 10
parralel 58.94018 64.96452 118.5969 71.42688 80.48588 316.9914 10
test test1 test3 test4 test5
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
4 4 4 4 4 4
5 5 5 5 5 5
6 6 6 6 6 6
7 7 7 7 7 7
8 8 8 8 8 8
9 9 9 9 9 9
10 10 10 10 10 10
11 11 11 11 11 11
12 12 12 12 12 12
13 13 13 13 13 13
14 14 14 14 14 14
15 15 15 15 15 15