许多巨大的CSV文件的高效合并

4
我有一个脚本,可以将目录中的所有csv文件进行外连接合并。问题是当我尝试使用它来合并需要加入的文件时(大约二十几个文件,每个文件6-12Gb),我的电脑会出现内存错误(MemoryError)。我知道itertools可以用于使循环更加高效,但我不清楚它是否适用于此情况,或者如何应用它。我能想到的另一种选择是安装mySQL,学习基础知识,并在那里完成此操作。显然,如果可能的话,我更愿意在Python中完成此操作,因为我已经在学习它了。如果有R语言解决方案也可以接受。

这是我的代码:

import os
import glob
import pandas as pd
os.chdir("\\path\\containing\\files")

files = glob.glob("*.csv")
sdf = pd.read_csv(files[0], sep=',')

for filename in files[1:]:
    df = pd.read_csv(filename, sep=',')
    sdf = pd.merge(sdf, df, how='outer', on=['Factor1', 'Factor2'])

任何关于如何处理文件太大而超出电脑内存的建议将不胜感激。
3个回答

6

使用HDF5,我认为这非常适合您的需求。它还处理out-of-core queries,因此您不必遇到MemoryError

import os
import glob
import pandas as pd
os.chdir("\\path\\containing\\files")

files = glob.glob("*.csv")
hdf_path = 'my_concatenated_file.h5'

with pd.HDFStore(hdf_path, mode='w', complevel=5, complib='blosc') as store:
    # This compresses the final file by 5 using blosc. You can avoid that or
    # change it as per your needs.
    for filename in files:
        store.append('table_name', pd.read_csv(filename, sep=','), index=False)
    # Then create the indexes, if you need it
    store.create_table_index('table_name', columns=['Factor1', 'Factor2'], optlevel=9, kind='full')

1
抛出了一系列错误,其中第一个是:在第2885行,运行代码时执行(code_obj, self.user_global_ns, self.user_ns) - Stonecraft
2
好的,谢谢。最终结果需要是csv格式,但我保存后也没有问题,对吧? 而且我需要合并的文件确实共享相同的列,之前出错是因为同一目录下有一个无关的文件。所以看起来你的解决方案可行! - Stonecraft
1
没有问题,你可以从HDF转换到csv。HDF只是让你能够进行外部查询,因此你可以很容易地进行连接。例如,你可以分块读取主表,提取“Factor1”和“Factor2”的值,并从所有其他表中获取包含这些值的行,将它们合并并写入csv文件。你会发现,HDF5比csv更快、更易于管理。因此,除非你有强烈的需求回到csv,否则我认为你最好留在HDF5上。而且,HDF5很快就会有ODBC驱动程序:https://hdfgroup.org/wp/tag/hdf5-odbc-driver/ - Kartik
1
由于您的文件共享相同的列结构,建议您也查看以下答案:https://dev59.com/r2Uo5IYBdhLWcg3wvRlF和https://dev59.com/zYLba4cB1Zd3GeqPir_T#25471765。它们将帮助您查询最终表格,以便您只得到在“Factor1”和“Factor2”中共享相同元素的行,这样您就可以轻松地重塑表格,以获得最终csv输出的并排表格。此外,请使用我之前的答案版本。 - Kartik
1
感谢提供的额外信息。我使用了您的代码并且它比之前尝试的快了很多(也就是说,它在没有错误的情况下完成的速度比初始尝试崩溃的速度要快)。我仍在努力学习如何在R中处理h5文件(我的目标是将数据合并),但似乎有很多可用的帮助,所以从这里开始我应该没问题了。已标记为已回答 :) - Stonecraft
显示剩余7条评论

0

有可能 dask 很适合您的使用。这可能取决于您在合并之后想要做什么。


我将把它保存为一个巨大的CSV文件。 - Stonecraft

0

我不确定自己是否理解流的工作原理,但我认为这可能是一个问题,因为我不仅仅是将行连接在一起,而是不同文件中相同键的存在或不存在会改变行的对齐方式。 - Stonecraft
只要它适合内存,你可以做任何想做的事情。按需读取所需的位,并将完整/匹配的内容刷新到磁盘上。 - Shawn K

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接