我有一个脚本,它使用外连接获取目录中的所有csv文件并将它们并排合并。问题是当我尝试在我需要加入的文件上使用它时,我的计算机会窒息(MemoryError)(每个文件大约有6到12个Gb)。我知道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'])
对于如何使用对我的计算机内存来说太大的文件执行此操作的任何建议将不胜感激。
答案 0 :(得分:4)
使用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 :(得分:0)
dask有可能非常适合您的使用。这可能取决于合并后您想要做什么。
答案 2 :(得分:0)
你应该可以用python做到这一点,但我不认为一次阅读csv会最有效地利用你的记忆。
How to read a CSV file from a stream and process each line as it is written?