如何用 esProc SPL 操作大 csv
esProc SPL 提供了游标运算,可以用非常简单的代码操作大 csv 文件,稍加改动就能变成并行计算,还有图形化界面,比 Pyhton 方便多了。
先去这里下载 esProc SPL:https://www.esproc.com/download-esproc/
懒得折腾源码的话可以用标准版,下载并安装。
准备好一个大 csv 文件:
打开 esProc IDE,新建脚本,在 A1 格写 SPL 代码,读取前 100 条:
=file("d:/OrdersBig.csv").cursor@tc().fetch(100)
函数 cursor 表示用游标打开文本文件,@表示函数的扩展选项,@t 表示首行为列名,@c 表示分隔符为逗号。
因为是大文件,全部读入内存可能溢出,所以只读 100 条看一下。
按 ctrl-F9 执行,可以在右边看到计算结果数据表。
SPL 代码写在单元格中,每个格执行后就会有个值,在右边可以看到,这会给调试带来很大的方便。
来试试计算,先数一下行数:
A | |
1 | =file("d:/OrdersBig.csv").cursor@tc() |
2 | =A1.skip() |
函数 skip 用来跳过 N 条记录并返回跳过的记录数,参数为空时跳过全部记录。
共有 101,730,411 条记录。
再看看过滤,选出 Amount 在 3000 至 4000 之间,Client 含有 s 的记录:
A | |
1 | =file("d:/OrdersBig.csv").cursor@tc() |
2 | =A1.select(Amount>3000 && Amount<=4000 && like@c(Client,"*s*")) |
3 | =A1.fetch(100) |
函数 select 用于条件过滤,函数 like 用于字符串匹配,* 是通配符,@c 表示不区分大小写。
因为可能结果还是很多,也只取前 100 条看看,执行结果在 A3:
排序也可以,比如按 OrderDate 的顺序、Amount 的逆序排序:
A | |
1 | =file("d:/OrdersBig.csv").cursor@tc() |
2 | =A1.sortx(OrderDate,-Amount) |
3 | =file("d:/result.csv").export@tc(A2) |
4 | =file("d:/result.csv").cursor@tc().fetch(100) |
排序后把结果写入新文件,再打开新文件,取前 100 条。函数 sortx 用于大文件排序,- 表示逆序。
执行后看右边结果,已经排好序了。
再做些复杂的运算,分组汇总:
A | |
1 | =now() |
2 | =file("d:/OrdersBig.csv").cursor@tc(OrderDate,Client,SellerID,Amount) |
3 | =A2.select(year(OrderDate)>=2020 || !Client || to(101,400).contain(SellerID)) |
4 | =A3.groups(year(OrderDate):y,month(OrderDate):m; sum(Amount):amt) |
5 | =output(interval@s(A1,now())) |
SQL 程序员一定对 A4 的 groups 函数很熟悉,这里就不多说了。
A2 打开游标时只读要用到的列,可以提高速度。这里还增加了 A1 和 A5 来统计运行时间,并打印在控制台:
可以看到运行时间:145 秒。
并行计算可以充分利用现在的多核 CPU,必须试一试。把上面代码改成并行计算,只要在 cursor 函数后简单加个选项 @m,其余不变:
A | |
1 | =now() |
2 | =file("d:/OrdersBig.csv").cursor@tcm(OrderDate,Client,SellerID,Amount) |
3 | =A2.select(year(OrderDate)>=2020 || !Client || to(101,400).contain(SellerID)) |
4 | =A3.groups(year(OrderDate):y,month(OrderDate):m; sum(Amount):amt) |
5 | =output(interval@s(A1,now())) |
@m 表示按照 option 里配置的并行选项进行多线程计算。
同时把这个并行选项打开。
现在执行一遍:
提升到了 92 秒,可能受到硬盘的并发限制,做不到倍数性能提升,用 2 线程跑的结果也差不多。
上面是几个基本运算,官网上对大 csv 计算的例子更加广泛深入,代码也都很简单,值得一看。
英文版 https://c.esproc.com/article/1742004791742