熊猫合并两个数据帧导致内存泄漏

时间:2020-08-15 07:41:33

标签: pandas dataframe csv merge memory-leaks

问题陈述:

我必须递归地对多个CSV文件执行类似于联接的SQL表。 示例:我有CSV1,CSV2,CSV3,..... CSVn

文件

我需要一次在两个CSV之间执行联接(内部/外部/左侧/完全),然后与第三个CSV执行联接结果,依此类推,直到所有CSV合并为止。

我尝试过的事情:

我正在使用pandas库合并方法(https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.merge.html)合并CSV文件的数据帧。

代码段:

import pandas as pd
 
df1 = pd.read_csv(path_of_csv1)
df2 = pd.read_csv(path_of_csv2)
resultant_df = df1.merge(df2, left_on='left_csv_column_name', right_on='right_csv_column_name', how='inner')
.....

我正在使用熊猫版本1.1.0和python版本3.8.5

我面临的问题:

我将Mac Book Pro与8Gb Ram配合使用,并尝试将Docker容器内部和外部的DataFrame合并。对于每个大约10Mb的较小CSV文件,我可以成功合并一些文件,但是对于一些较大的CSV文件,可以说每个50Mb我都面临内存泄漏问题。在开始合并操作之前,我的系统从6 GB中分配了3.5 GB可用ram(用docker stats <container_name>检查)分配给docker,并且一旦开始合并过程,docker将消耗整个可用RAM,并且合并过程在终止之间终止-9信号错误。

我也尝试过将它们合并到容器之外。相同的内存问题仍然存在,并且我的进程/终端介于两者之间。

PS:请原谅如果写错了东西。

任何帮助将不胜感激。我完全陷入了合并过程中。

1 个答案:

答案 0 :(得分:1)

您的问题

我认为您没有内存泄漏,但是合并后的数据帧太大而无法容纳在内存中。确实,memory leak是指对象没有被系统正确删除(收集的垃圾)并累积,导致内存随时间膨胀。

即使两个数据帧都可以保存在RAM中,合并操作也可能导致更大的数据帧,从而导致内存问题。例如,如果合并列中有很多重复的值,则可能会发生这种情况:

>>> df1 = pd.DataFrame({'col': ['a', 'a', 'a', 'b']})
>>> df2 = pd.DataFrame({'col': ['a', 'a', 'a', 'c']})
>>> df1.merge(df2, on='col')
  col
0   a
1   a
2   a
3   a
4   a
5   a
6   a
7   a
8   a

这里,结果数据帧中有9行,这比初始数据帧的总和还多!这是因为合并操作会创建数据的笛卡尔积(此处:df1的第1行与df的第1、2和3合并; df1的第2行与第1、2的行合并和3等)

现在想象最坏的情况,即在两个合并列中只有一个一个值。如果在每个df中有10^5行,您将以10^10行结尾。这可能是您的问题。

解决方案

要执行无法容纳在内存中或结果太大的数据帧的合并,可以尝试使用dask库。例如,请参见对此SO question的答案。