统计大xlsx文件的速度尝试
创作者俱乐部成员
一直有个疑问,在批量处理大一点的xlsx文件,比如10万行的表时,哪种方法更快?
于是今天的问题是:当前目录有多个xlsx文件,每个文件内部只有一张表,表内有两列,x列是数字,y列是分类,现在要对当前目录的所有xlsx里,每一个分类对应的数字求和
先试试JS宏
let f = Dir(ThisWorkbook.Path + "\\*.xlsx")
while (f !== "") {
let wb = Workbooks.Open(ThisWorkbook.Path + "\\" + f)
}
代码写的很烂,主要就是上面这样用Dir遍历xlsx文件,然后用字典分类求和
可以看出,主要是打开关闭文件这个步骤浪费时间
再试试pwsh里通过sql查询方式
👋 | dir *.xls? | %{Get-SQL -Excel -Connection $_.Name -SQL 'select y,sum(x) as s from [Sheet1$] group by y' -Close -Quiet;$_.Name|Out-Host} | %{$d[$_.y]+=$_.s} |
用的是access database engine,只是pwsh里用起来简单
可以看出,还是逐个打开表最耗时间,但相比JS宏,似乎快了一点
然后是python
没想到openpyxl打开大一点的xlsx速度更慢
好处是什么系统都能用这个脚本,包括手机上也可以
也许用xlrd或pandas打开能快一点?但据说pandas过去也是用的openpyxl
总之,py在打开大一点的xlsx时不够快
最后来试试新玩具,nushell
📌 | ls *.xlsx | par-each {open $in.name | get Sheet1 | headers | group-by --to-table y | each {{...($in.items | math sum) "y": ($in.group)}}} | flatten | group-by --to-table y | each {{...($in.items | math sum) "y": ($in.group)}} |
刚开始用,写的很烂。。。
但是,居然只用1秒就全处理了?!!
nushell这东西刚出来没多久,更新非常活跃,有很多好处:
用rust重写的现代化shell,rust保证了开发的速度和安全性,同时能达到c的执行速度
主要用来处理结构化的数据,包括xlsx表,数据库,csv、xml等格式
遍历操作用each,由于它采用了函数式编程的思想,不可变的变量、纯函数等,可以直接改用par-each并发循环!
可以方便的写sql查询数据,或是使用rust里的DataFrame(类似pandas)处理数据,速度非常快
最后总结一下经验:
JS宏和access的sql查询速度都可以接受,需要逐个打开文件,处理后关闭,这个步骤耗时较多
python的库不依赖office,相当于直接解压xlsx解析xml,逐个打开大一点的表格,速度很慢。虽然可以写并发,但python有全局锁的限制,协程没有这方面的方法,所以只能用多进程。虽然写起来麻烦,但速度可以提升,加上可以跨平台,还是蛮好用的
nushell很惊喜,rust重写的现代化shell,噱头十足,each改成par-each直接就可以并发循环让人眼前一亮,处理结构化数据包括xlsx,且可以使用DataFrame和SQL,满足大部分需求,尤其是需要并发时,十分值得尝试👍
创作者俱乐部成员
创作者俱乐部成员