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

如何在Jupyter Notebook中实现状态依赖式缓存?

问题描述

我在Jupyter Notebook里有个计算成本极高的大型中间DataFrame,想跨会话缓存它,但要是生成这个DataFrame的上游变量(比如过滤后的新数据)变了,得自动重新计算才行。有没有办法把缓存变量和任意数量的"状态"变量绑定,检测到状态变化就重新计算目标变量,没变化就直接从缓存加载?

已参考的相关方案及存在的问题

  • 使用%store魔法命令:能实现跨会话缓存,但必须手动触发重新计算,没法自动感知上游变量的变化。
  • 使用dill保存整个会话:可以保存会话内容,但体积太大,我只想存计算成本高的中间值,不想把整个会话都保存下来。

期望的使用示例

假设Notebook中的单元格用# ---- #分隔

# 初始化工作:加载并清洗数据集
df = load_dataset()
df = clean_dataset()

# 生成后续会用到的中间变量
s1, s2, s3 = compute_intermediate_variables()

# ---- #

# 高计算成本单元格
def compute(df, s1, s2, s3):  # 定义耗时的计算逻辑
    return some_func(df, s1, s2, s3)

# 希望在这里使用缓存操作,自动根据df、s1、s2、s3的变化决定是重新计算还是加载缓存

可行解决方案

方案1:用joblib实现带依赖校验的缓存

joblib能高效序列化大型NumPy数组和DataFrame,还可以通过计算输入参数的哈希值判断是否需要重新计算。

步骤:

  1. 安装joblib:pip install joblib
  2. 编写缓存逻辑,通过哈希值校验输入变量是否变化:
from joblib import Memory
import hashlib
import pandas as pd
import pickle

# 创建缓存存储目录
memory = Memory(location='./cached_data', verbose=0)

def get_var_hash(var):
    """生成变量的唯一哈希值,用于检测变量是否变化"""
    if isinstance(var, pd.DataFrame):
        # 针对DataFrame生成哈希,包含数据、列顺序和类型信息
        return hashlib.sha256(pd.util.hash_pandas_object(var, index=True).values).hexdigest()
    else:
        # 其他类型变量序列化后生成哈希
        return hashlib.sha256(pickle.dumps(var)).hexdigest()

@memory.cache(ignore=['df_hash', 's1_hash', 's2_hash', 's3_hash'])
def cached_compute(df_hash, s1_hash, s2_hash, s3_hash, df, s1, s2, s3):
    return some_func(df, s1, s2, s3)

# 生成依赖变量的哈希值,传入缓存函数
df_hash = get_var_hash(df)
s1_hash = get_var_hash(s1)
s2_hash = get_var_hash(s2)
s3_hash = get_var_hash(s3)

# 获取结果:依赖变量不变则加载缓存,变了则重新计算
result_df = cached_compute(df_hash, s1_hash, s2_hash, s3_hash, df, s1, s2, s3)

方案2:使用jupyter-cache专用工具

jupyter-cache是专为Jupyter Notebook设计的缓存工具,支持基于单元格输入输出的缓存,还能自定义依赖项。

步骤:

  1. 安装工具:pip install jupyter-cache
  2. 在Notebook中加载扩展:
%load_ext jupyter_cache
  1. 用%%cache魔法命令标记需要缓存的单元格,并指定依赖变量:
%%cache high_cost_compute --deps df s1 s2 s3
def compute(df, s1, s2, s3):
    return some_func(df, s1, s2, s3)

result_df = compute(df, s1, s2, s3)

这个魔法命令会自动跟踪指定的依赖变量,只要df、s1、s2、s3中有一个变化,就会重新执行单元格;否则直接加载缓存好的result_df。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 07:35:56