You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

函数内提取pandas DataFrame名保存相关性图文件名异常问题

问题根因

你写的get_df_name通过遍历globals()匹配对象的逻辑天生不稳定,和变量名是否包含下划线没有关系:

  • globals()会返回全局作用域下所有变量,除了你自定义的DataFrame,还包括Python运行时自动生成的临时变量、导入的模块/函数;如果你是在IPython/Jupyter环境下运行,还会自动生成_、__、___三个临时变量,分别存放最近3次单元格执行的输出结果。
  • 你用is做身份匹配时,如果这些下划线开头的临时变量恰好指向你传入的DataFrame(比如你之前单独运行过df_nodate没有做赋值,IPython就会自动把这个对象绑定到_类临时变量上),列表推导取第一个匹配项[0]时,就会先拿到这些短的下划线变量名,最终拼接出cor__.png这类错误文件名。
  • 这个写法还有其他隐患:如果同一个DataFrame被赋值给多个全局变量,取到的名字完全由globals遍历顺序决定,结果随机;如果传入的DataFrame是函数内部生成的局部变量,还会直接触发索引越界报错。
修复方案

不要通过遍历全局作用域反查变量名,最稳妥的方案是调用时显式传入保存文件名,不想额外传参的话,可以通过解析调用栈的源码文本获取传入参数的原始变量名,稳定性远高于扫globals的方案:

import seaborn as sns
import os
import matplotlib.pyplot as plt
import inspect

def get_df_name(df):
    # 读取上一级调用栈的代码内容,提取第一个位置参数的原始文本
    prev_frame = inspect.currentframe().f_back
    code_line = inspect.getframeinfo(prev_frame, context=1).code_context[0].strip()
    first_param = code_line[code_line.index("(")+1:].split(",")[0].strip()
    return first_param

def cor(data, figsize):
    # 自动创建输出目录,避免路径不存在报错
    os.makedirs("cor_plots", exist_ok=True)
    fig = plt.figure(figsize=figsize)
    corr = data.corr()
    ax = sns.heatmap(
        corr, 
        vmin=-1, vmax=1, center=0,
        cmap=sns.diverging_palette(20, 220, n=200),
        square=True,
        annot=True
    )
    ax.set_xticklabels(
        ax.get_xticklabels(),
        rotation=45,
        horizontalalignment='right'
    )
    
    df_name = get_df_name(data)
    path = os.path.join("cor_plots", f"cor_{df_name}.png")
    # 增加tight布局避免标签截断,存完关闭图对象释放内存
    fig.savefig(fname=path, bbox_inches="tight")
    plt.close(fig)

这个实现直接读取你写的cor(xxx, figsize=...)那行代码,提取第一个入参的原始文本作为变量名,不会被全局作用域的临时变量干扰。如果遇到传入的是表达式(比如cor(df_nodate.dropna(), (8,6))),提取到的会是表达式文本,这种场景可以给cor函数加个可选的save_name参数,特殊场景手动指定文件名即可。

内容的提问来源于stack exchange,提问作者miaa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 21:36:22