Ipython使用%store magic来检索动态名称

Pur*_*uck 5 python memory-leaks ipython jupyter-notebook

我正在尝试编写一个函数,使用magic命令检索指定名称下的文件%store. .例如,如果我已经存储了一个文件,"df"但后来想要在名称"frame"下检索它,那么我想用函数调用该函数retrieve('df','frame') 之后,变量帧将包含先前存储为df的数据帧.

但是,我不知道如何做到这一点,下面的函数只返回

"没有存储变量outputfile"

import IPython
import gc
import os
import numpy as np
import pandas as pd

path = IPython.paths.get_ipython_dir()+'\profile_default\db\\autorestore\\'
Run Code Online (Sandbox Code Playgroud)

函数检索指定名称下的存储文件(inputfile)(outputfile)

def retrieve(inputfile,outputfile='temp'):
    os.rename(r''+path+inputfile,r''+path+outputfile)
    %store -r outputfile
    os.rename(r''+path+outputfile,r''+path+inputfile)
    return


In [48]: retrieve('df','frame')
returns "no stored variable outputfile"
Run Code Online (Sandbox Code Playgroud)

关于这个/背景的原因的更多细节

主要原因是释放内存.我有一些文件,我检索使用%store,然后做一些操作或合并到另一个dataframe.在此之后我想释放使用的内存,但%xdel在使用检索的文件上运行%store -r并不释放内存.

因此我写了下面的函数,它在变量名temp下检索存储的文件.然后,我可以通过检索空文件作为临时释放内存.

#function to retrieved a stored file (inputfile) unde the variable name temp
def retrieve_temp(inputfile):
    os.rename(r''+path+inputfile,r''+path+'temp')
    %store -r temp
    os.rename(r''+path+'temp',r''+path+inputfile)
    return
Run Code Online (Sandbox Code Playgroud)

例如,在检索任何当前ram使用之前

In [5]: ram_usage()
Out[5]: '107mb'
Run Code Online (Sandbox Code Playgroud)

然后我检索一个文件并查看新的ram用法

In[6]: (retrieve_temp('comps'),ram_usage())[1]
Out[6]: '2520mb'
Run Code Online (Sandbox Code Playgroud)

运行%xdel后,使用率保持不变

In[12]: %xdel temp
In[13]: ram_usage()
Out[13]: '2520mb'
Run Code Online (Sandbox Code Playgroud)

检索名为"temp"的空文件后,释放ram

In [14]: (retrieve_temp('b'),ram_usage())[1]
Out [14]: '114mb'
Run Code Online (Sandbox Code Playgroud)

这解决了我的大部分内存问题,但是,有时我需要同时处理多个帧.

因此,我希望有一个更通用的功能,我可以指定用于临时帧的名称,以后可以轻松释放内存.通过为临时数据帧使用更具描述性的名称,这也有助于使我的代码更具可读性.

我想知道是否有办法让我的第一个功能工作(不必使用%store魔法,但我不想自己腌制文件)

或者,如果有另一种方法来释放使用%store magic命令检索的变量所使用的内存,请告诉我.(我尝试%xdel, del, %reset, gc.collect(),启动sub-processes但效果不佳,到目前为止,唯一可行的方法是重置内核或使用相同名称检索空文件)

非常感谢,

Pur*_*uck 1

经过更多挖掘后,我找到了调用魔术命令的函数并使用了它。 get_ipython().run_line_magic('store', '-r '+outputfile)

修改后的函数如下(请注意,如果您使用此函数,您可能希望通过添加一些行来临时重命名您已存储在名称“outputfile”下的任何文件来使其更加健壮)

import IPython
import os
import gc
#function to retrieve a stored file (inputfile) under a specified name (outputfile)
def retrieve(inputfile,outputfile='temp'):
    path = IPython.paths.get_ipython_dir()+'\profile_default\db\\autorestore\\'
    os.rename(r''+path+inputfile,r''+path+outputfile)
    get_ipython().run_line_magic('store', '-r '+outputfile)
    os.rename(r''+path+outputfile,r''+path+inputfile)
    gc.collect() #needed to free memory after returning an empty file
    return
Run Code Online (Sandbox Code Playgroud)

只要我在再次删除之前不运行笔记本并将检索到的数据帧中的任何内容打印到单元格中,这似乎就可以解决我所有的内存泄漏问题。

新内存使用:

简而言之,在完成了称为 的变量后df_temp,您可以运行retrieve('emptyfile','df_temp'),只要您没有将任何结果打印到单元格中,您的内存现在应该被完全清除

In [14]: ram_usage()
Out [14]: '101mb'
In [15]: retrieve('SFBkgs - Copy','df_temp')
In [16]: ram_usage()
Out [16]: '1281mb'
In [17]: df_temp.head(); #if I don't use ; to stop the printing of the output the below still fails to free the ram
In [18]: %xdel df_temp #this still doesn't free the ram
In [19]: ram_usage()
Out [19]: '1281mb'
In [20]: gc.collect()
Out [20]: 7
In [21]: ram_usage() #the garbage collector didn't help
Out [21]: '1281mb'
In [22]: retrieve('emptyfile','df_temp') #retrieves an empty file as df_temp
In [23]: ram_usage() #the memory has now been freed
Out [23]: '103mb'
Run Code Online (Sandbox Code Playgroud)