【发布时间】:2020-02-14 21:35:45
【问题描述】:
我目前有一个脚本,可以将多个 csv 文件合并为一个,该脚本工作正常,但当开始使用较大的文件时,我们会很快耗尽内存。这是一个问题,原因之一是脚本在 AWS 服务器上运行,并且内存不足意味着服务器崩溃。 目前每个文件大小限制为 250mb 左右,这将我们限制为 2 个文件,但是由于我工作的公司是生物技术公司并且我们使用的是基因测序文件,我们使用的文件大小范围从 17mb 到大约 700mb取决于实验。我的想法是将一个数据帧加载到整个内存中,然后将其他数据帧分块并迭代组合,这效果不太好。
我的数据框与此类似(它们的大小可能不同,但有些列保持不变;“Mod”、“AA”和“Nuc”)
+-----+-----+-----+-----+-----+-----+-----+-----+
| Mod | Nuc | AA | 1_1 | 1_2 | 1_3 | 1_4 | 1_5 |
+-----+-----+-----+-----+-----+-----+-----+-----+
| 000 | ABC | ABC | 10 | 5 | 9 | 16 | 8 |
+-----+-----+-----+-----+-----+-----+-----+-----+
| 010 | CBA | CBA | 0 | 1 | 4 | 9 | 0 |
+-----+-----+-----+-----+-----+-----+-----+-----+
当组合两个框架时,我需要它们在“Mod”、“Nuc”和“AA”上合并,这样我就有了类似的东西
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| Mod | Nuc | AA | 1_1 | 1_2 | 1_3 | 1_4 | 1_5 | 2_1 | 2_2 | 2_3 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 000 | ABC | ABC | 10 | 5 | 9 | 16 | 8 | 5 | 29 | 0 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 010 | CBA | CBA | 0 | 1 | 4 | 9 | 0 | 0 | 0 | 1 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
我已经有代码来更改标题的名称,所以我不担心,但是当我使用块时,我最终会得到更接近的东西
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| Mod | Nuc | AA | 1_1 | 1_2 | 1_3 | 1_4 | 1_5 | 2_1 | 2_2 | 2_3 | 3_1 | 3_2 | 3_3 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 000 | ABC | ABC | 10 | 5 | 9 | 16 | 8 | 5 | 29 | 0 | NA | NA | NA |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 010 | CBA | CBA | 0 | 1 | 4 | 9 | 0 | NA | NA | NA | 0 | 0 | 1 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
基本上,它将每个块视为一个新文件,而不是来自同一个文件。
我知道它为什么这样做,但我不确定如何解决这个问题,现在我的分块代码非常简单。
file = "tableFile/123456.txt"
initDF = pd.read_csv(file, sep="\t", header=0)
file2 = "tableFile/7891011.txt"
for chunks in pd.read_csv(file2, sep="\t", chunksize=50000, header=0):
initDF = initDF.merge(chunks, how='right', on=['Mod', "Nuc", "AA"])
正如您所见,正如我所说,我知道它为什么会这样做,但我对 Pandas 和数据框连接都没有经验,无法修复它,因此非常感谢任何帮助。当我在堆栈和谷歌上搜索时,我也找不到类似的东西。
【问题讨论】:
-
您可以尝试在最后一行添加 copy(),以告诉 pandas 不要更新而是从添加的块中创建一个新的数据框。
-
initDF = initDF.merge(chunks, how='outer', on=['Mod', "Nuc", "AA"]).copy()
-
感谢您的确认。刚试了一下,输出没有任何区别。
-
initDF = initDF.merge(chunks, how='outer', on=['Mod', "Nuc", "AA"], indicator="both") 如果这不起作用试试这也是。 initDF = initDF.merge(chunks, how='outer', on=['Mod', "Nuc", "AA"], copy=False)
-
感谢您的帮助弗洛里安,我尝试了这两种方法,但都没有奏效。不过我想通了。基本上通过检查列名,我可以决定是使用merge() 还是concat()。因此,如果卡盘中的列存在于 initDF 中,那么我知道我已经合并了一次,然后 concat() 将使其按预期工作
标签: python pandas dataframe merge