新人提问:快速 merge 大量 csv 文件

2019-09-02 16:30:58 +08:00
 allenloong
最近在折腾把 1000+csv 文件进行合并,每个 csv 大约有 600 万条,4 列,合并完后最多有 2000 万条( 1000+列)。单个 csv,其中一列为 string,其余三列是 int。

example_csv:

col1| col2 |col3| col4
---------------------------
str1 10001 16000 1
str1 17000 17005 0
str2 13333 23333 1

合并以前三列为 index,已经尝试 pandas merge 和 join,但是速度慢,128G 的内存也不够用。尝试用了 pyspark,能够很快的 join 完 1000 个文件,内存也不会很夸张,但是没有办法把合并好的 dataframe 写出。

想请教下,有没有什么的有效率的办法解决这个问题,谢谢。
3688 次点击
所在节点    Python
38 条回复
xypty
2019-09-02 17:54:10 +08:00
@allenloong 可以考虑一下 mongo,mongo 我觉得还可以
tinybaby365
2019-09-02 17:56:52 +08:00
不知道为什么要合并,意义何在?如果为了方便存储管理,那就打成一个 tar 包。

实在想不到合并成一个大文件的好处,以后完全没法并行处理啊……
xomix
2019-09-02 17:57:17 +08:00
这种建议是第一个文件直接复制,第二和第三个文件直接从固定字节开始读取(从第一个文件判断表头长度)后追加到复制的文件后。
这样应该最快,再加上一些大文件复制的缓存等机制还能更快点。
letking
2019-09-02 17:58:49 +08:00
@allenloong 依次导入每个文件为一张表,然后 join 导入的表,保存成中间表。跟你现在的流程一样。
allenloong
2019-09-02 18:00:15 +08:00
@tinybaby365 #22 因为想用合并好的表去做后面的计算,但是计算要求的表就是这样。
allenloong
2019-09-02 18:03:34 +08:00
@letking #24 还是用 spark 或者任意数据库?
allenloong
2019-09-02 18:04:12 +08:00
@xomix #23 没有太明白 XD
letking
2019-09-02 18:07:04 +08:00
@allenloong mysql 应该就可以。
spark 之所以这么搞不行是因为 spark 是把所有数据都加载的内存里处理的,而数据库是把数据存磁盘的。
如果你有 hadoop 集群的话可以用 spark 这么做。
allenloong
2019-09-02 18:08:33 +08:00
@letking #28 明白了 我试试 谢谢你
corefx
2019-09-02 18:13:58 +08:00
楼上这么多回复,看的我一脸问号,斗胆问下下合并文件跟内存有什么关系?直接操作文件流,从源文件读取一行,向目标文件写入一行,全部内存开销就是 1 行文本啊!!!
aheadlead
2019-09-02 18:18:12 +08:00
分治?类似于归并排序?
letking
2019-09-02 18:23:39 +08:00
@corefx 好好看看楼主的问题?
cigarzh
2019-09-02 18:31:11 +08:00
上数据库
rrfeng
2019-09-02 18:48:02 +08:00
如果有序,就是个归并排序,可以边排边写。
如果无序,至少要把 index 存起来,可以用 hash 或者原始值,2000w 的 index 算一下内存需要多少?

最后按 hash 输出即可。


awk '{a[$1$2$3]+=$4}END{for(i in a) print i,a}' *.csv
guyskk0x0
2019-09-03 09:53:25 +08:00
遍历所有行,按 hash(col1,2,3) % N 分组写到 N 个文件,相同的 key 都在同一个文件。
再对每个文件分别做合并。
最终结果直接 concat 即可。
allenloong
2019-09-03 14:05:41 +08:00
@guyskk0x0 #35 emmmm 如果按照 hash 把文件进行了拆分,合并的时候怎么保证每个小文件的列能够对应上呢?
vimiix
2019-09-03 17:55:56 +08:00
尝试下 dpark?
cassidyhere
2019-09-03 18:29:29 +08:00
先读所有文件的第一行构造出最终的 columns,再遍历文件

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/597244

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX