我有一个Jupyter笔记本。我知道它不适合大型作品,但在许多情况下,它是我必须使用的工具。
经过一些计算,我最终在内存中得到了几只我想腌制的熊猫DataFrame
。所以我做
df_name.to_pickle(filename)
然而,我想使用创建一个所有DataFrame的列表
df_list = %who DataFrame
然后我想做一些类似的事情
for varname in df_list:
varname.to_pickle(f'{varname}.pickle')
这当然不起作用,因为varname
是一个字符串,而不是具有关联.to_pickle
方法的DataFrame
对象
所以我愚蠢的问题是,访问实际对象varname
的最佳方式是什么,而不仅仅是访问具有其名称的字符串?
注意:如果我创建一个实际DataFrame
的列表,这些对象在内存中是相当大的,所以我可能会遇到内存问题。
感谢
@matszwecja在评论中指出,最合理的方法是在制作时收集它们。这对你自己和其他人来说也将是最清楚的。此外,在开发代码时更健壮、更易于调试
然而,您似乎在更抽象地考虑对内核命名空间中的数据帧进行迭代,并且有可能做到这一点,并逐步自动清除数据帧。也许这并不是那么容易。例如,您已经发现无法使用df_list = %who DataFrame
简单地创建可用列表。(它显示输出单元格中的名称,但不是Python可以使用的方式。(
如果你真的想这样做,这里有一个选项会起作用。第一部分设置一些伪数据帧,然后列出它们的字典:
import pandas as pd
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
input ='''
River_Level Rainfall
0.876 0.0
0.877 0.8
0.882 0.0
0.816 0.0
0.826 0.0
0.836 0.0
0.817 0.8
0.812 0.0
0.816 0.0
0.826 0.0
0.836 0.0
0.807 0.8
0.802 0.0
'''
df_name_one = pd.read_table(StringIO(input), header=0, index_col=None, delim_whitespace=True)
input ='''
River_Level Rainfall
0.976 0.1
0.977 0.5
0.982 0.0
0.916 0.3
0.926 0.0
0.996 9.0
0.917 0.8
0.912 0.0
0.916 0.0
0.926 0.1
0.836 0.0
0.907 0.6
0.902 0.0
'''
df_name_two = pd.read_table(StringIO(input), header=0, index_col=None, delim_whitespace=True)
list_of_dfs_dicts = []
for obj_name in dir():
obj_type_str = str((type(eval(obj_name))))
#print(obj_type_str)
if "DataFrame" in obj_type_str:
#print(obj_name)
#print(obj_type_str)
list_of_dfs_dicts.append({obj_name: eval(obj_name)})
现在,列表中的每个条目都是数据帧对象和数据帧的名称。这可以通过笔记本中的一行进行迭代和腌制:
[df.to_pickle(f'{varname}.pkl') for d in list_of_dfs_dicts for varname,df in d.items()];
这实际上相当于这个,更容易阅读:
for d in list_of_dfs_dicts:
for varname,df in d.items():
df.to_pickle(f'{varname}.pkl')
对于这个独立的答案,我将整个数据帧作为收集的列表和字典的一部分列出。对于这些数据帧,内存不是一个问题,我希望它能以小步骤很好地说明问题。
然而,记忆是你关心的问题。您可以改变收集步骤,不将整个数据帧添加到列表中,如下所示:
import pandas as pd
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
input ='''
River_Level Rainfall
0.876 0.0
0.877 0.8
0.882 0.0
0.816 0.0
0.826 0.0
0.836 0.0
0.817 0.8
0.812 0.0
0.816 0.0
0.826 0.0
0.836 0.0
0.807 0.8
0.802 0.0
'''
df_name_one = pd.read_table(StringIO(input), header=0, index_col=None, delim_whitespace=True)
input ='''
River_Level Rainfall
0.976 0.1
0.977 0.5
0.982 0.0
0.916 0.3
0.926 0.0
0.996 9.0
0.917 0.8
0.912 0.0
0.916 0.0
0.926 0.1
0.836 0.0
0.907 0.6
0.902 0.0
'''
df_name_two = pd.read_table(StringIO(input), header=0, index_col=None, delim_whitespace=True)
df_list = []
for obj_name in dir():
obj_type_str = str((type(eval(obj_name))))
if "DataFrame" in obj_type_str:
df_list.append(obj_name)
for df_name in df_list:
eval(df_name).to_pickle(f'{df_name}.pkl')
请记住,尽管eval()
需要小心使用。特别是它打开了代码注入的大门
这样做并不是在检查。例如,在开发过程中,您可能会在某个时刻错误地生成大量数据帧(例如(,如果这些数据帧仍在内核的命名空间中,则它们将ALL通过酸洗步骤进行酸洗。这就是为什么收集你想要的东西更实用的原因;从长远来看更安全/稳健。我只是觉得你使用df_list = %who DataFrame
的想法很有趣。