pandas - Pandas 合并两个 DataFrame 导致内存泄漏
问题描述
问题陈述:
我必须递归地对多个 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 Pro8Gb Ram
并尝试合并 docker 容器内外的 DataFrame。对于每个大约 10Mb 的较小 CSV 文件,我能够成功合并一些文件,但对于一些较大的 CSV 文件,假设每个 50Mb 我面临内存泄漏问题。在开始合并操作之前,我的系统在 6 GB 中分配给 docker 的 3.5 GB 可用内存(选中docker stats <container_name>
),一旦启动合并过程,docker 会消耗整个可用内存,合并过程在两者之间终止,并出现 kill-9 信号错误。
我也尝试将它们合并到容器外。同样的内存问题仍然存在,我的进程/终端挂在两者之间。
PS:请原谅如果写错了。
任何帮助将非常感激。我完全陷入了这个合并过程。
解决方案
你的问题
我认为您没有内存泄漏,但生成的合并数据帧太大而无法放入内存。实际上,内存泄漏是指对象没有被系统正确删除(垃圾收集)并累积,导致内存随时间膨胀。
即使您的两个数据框都可以保存在 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的示例答案。
推荐阅读
- python - Python中的渠道归因(马尔可夫链模型)
- asp.net-web-api - 多层授权
- javascript - 为什么我无法在正文部分获取传递的参数?
- python - 张量流中双向 LSTM 的输入
- python - Python (flask/marshmallow)ValueError: too many values to unpack (expected 2)
- google-drive-api - 枚举 gogle 团队驱动器中管理员不属于其中的文件
- python - Python:正则表达式与所需的相反
- docker - Docker 错误:无法为服务创建容器,没有这样的文件或目录
- ruby-on-rails - 在 Rspec 的参数中传递空值哈希键
- php - 重定向以某种方式添加了斜杠