使用mplfnance/matplotlib时可能存在内存泄漏.如何解决



我正试图为CNN制作大量(约170万张(图像(带音量的蜡烛图(。然而,据我所知,我目前拥有的脚本在每次迭代后都会不断增加内存使用量,每次迭代大约2-5mb。无论我运行了多少个脚本实例,这种情况都会增加,直到我的内存完全满为止。(其中16gb,脚本最终使用11-12gb(。

目标是同时运行脚本的多个实例。我尝试了并行处理,结果没有那么好。因此,我只是简单地使用多个内核。我尝试了很多方法来减少内存使用,但似乎都不起作用。

我在VS代码中使用Jupyter笔记本电脑(Python 3.8.5((anaconda(,有一个64位的Windows系统。16GB RAM和Intel i7第8代

First Cell调用包,加载数据并设置参数。

# import required packages 
import matplotlib.dates as mpdates 
import matplotlib.pyplot as plt 
import mplfinance as mpf
import matplotlib as mpl
from PIL import Image
import pandas as pd 
import math as math
import numpy as np
import io   as io
import gc   as gc
import os as os

#set run instance number
run=1
#timeframe
tf = 20
#set_pixels
img_size=56
#colors
col_up = '#00FF00'
col_down = '#FF0000'
col_vol = "#0000FF"
#set directory
direct = "C:/Users/robin/1 - Scriptie/images/"
#loading the data
data1 = pd.read_csv(r'D:1 - SchoolEconometrics2020 - 2021ScriptieExplainable AIScriptsDatatest_data.csv',header=[0, 1] , index_col = 0 )
data1.index=pd.to_datetime(data1.index)
#subsetting the data
total_symbols = math.floor(len(data1.columns.unique(level=0))/6)
symbols1 = data1.columns.unique(level=0)[(run-1)*total_symbols:run*total_symbols]
#set the plot parameters
mc = mpf.make_marketcolors(up = col_up ,down = col_down, edge='inherit', volume= col_vol, wick='inherit')
s  = mpf.make_mpf_style(marketcolors=mc)   

第二个单元格定义了用于绘制图表的函数:

# creating candlestick chart with volume
def plot_candle(i,j,data,symbols,s,mc,direct,img_size, tf):

#slicing data into 30 trading day windows
data_temp=data[symbols[j]][i-tf:i]  
#creating and saving the candlestick charts
buf = io.BytesIO()
save = dict(fname= buf, rc = (["boxplot.whiskerprops.linewidth",10]), 
pad_inches=0,bbox_inches='tight')
mpf.plot(data_temp,savefig=save, type='candle',style=s, volume=True, axisoff=True,figratio=(1,1),closefig=True)
buf.seek(0)
im = Image.open(buf).resize((img_size,img_size))
im.save(direct+"/"+str(symbols[j])+"/"+str(i-tf+1)+".png", "PNG")
buf.close()
plt.close("all")

第三个单元格循环遍历数据并调用第二个单元格中的函数。

#check if images folder excists, if not, create it. 
if not os.path.exists(direct):
os.mkdir("C:/Users/robin/1 - Scriptie/images")
for j in range(0,len(symbols1)):
#Check if symbol folder excists, if not, create it 
if not os.path.exists(direct+"/"+symbols1[j]):
os.mkdir(direct + "/"+symbols1[j])
for i in range(tf,len(data1)) :
#check if the file has already been created
if not os.path.exists(direct+"/"+str(symbols1[j])+"/"   +str(i-tf+1)+".png"):
#call the functions and create the 
plot_candle(i , j , data1 , symbols1 ,s ,mc ,direct , img_size, tf)
gc.collect()

从评论中推广:

问题是,默认情况下,Matplotlib试图使用基于GUI的后端(它为每个绘图创建一个GUI窗口(。当你关闭它们时,我们会删除我们的一面,并告诉GUI删除它(基于c++(的一面。然而,这种拆卸发生在GUI事件循环上,在这种情况下,该事件循环从未运行过,因此c++端的对象在";即将被删除";状态,直到内存耗尽。

通过将后端设置为'agg',我们根本不想创建任何GUI窗口,因此没有GUI对象可拆卸(最好的优化是不做这件事;((。我希望它在墙上的时间也会稍微快一点(因为再说一遍,不要做你不需要做的工作!(。

请参阅https://matplotlib.org/tutorials/introductory/usage.html#backends有关后端的更多详细信息,请参阅https://matplotlib.org/users/interactive.html以及关于GUI集成如何工作的链接。

最新更新