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

如何为包含Pandas Series可变参数的函数实现记忆化?

为参数是Pandas Series的函数实现记忆化

首先得明确:你直接用lru_cache会报错,因为Pandas Series是可变对象,默认不支持哈希,而lru_cache需要参数是可哈希类型才能作为缓存的键。下面给你几个实用的解决办法:

方案一:自定义装饰器,将Series转为可哈希类型

我们可以写一个装饰器,把传入的Series转换成元组(元组是可哈希的),再用lru_cache对转换后的参数做缓存。这样既保留了原函数的参数形式,又实现了记忆化:

from functools import lru_cache, wraps
import pandas as pd

def series_cache(func):
    @wraps(func)
    def wrapper(series):
        # 将Series转换为元组作为缓存键
        cache_key = tuple(series)
        return cached_func(cache_key)
    
    @lru_cache(maxsize=None)
    def cached_func(cache_key):
        # 把元组转回Series,调用原函数
        series = pd.Series(cache_key)
        return func(series)
    
    return wrapper

# 使用自定义装饰器代替lru_cache
@series_cache
def fib(n):
    if n.iloc[0] == 1 or n.iloc[0] == 2:
        return 1
    min1 = n.copy()
    min1.iloc[0] -= 1
    min2 = n.copy()
    min2.iloc[0] -= 2
    return fib(min1) + fib(min2)

# 测试调用
print(fib(pd.Series([15, 0])))  # 输出610

这个方案的好处是不需要修改原函数的逻辑,完全兼容你原来的参数形式。

方案二:提取Series中关键的可哈希参数(简化版)

如果你的函数逻辑只依赖Series中的特定元素(比如例子里只用了第一个元素n.iloc[0]),那可以直接提取这个值作为函数参数,这样就能直接用lru_cache了:

from functools import lru_cache
import pandas as pd

@lru_cache(maxsize=None)
def fib(n):
    if n == 1 or n == 2:
        return 1
    return fib(n-1) + fib(n-2)

# 调用时从Series提取关键值
print(fib(pd.Series([15, 0]).iloc[0]))  # 输出610

这个方法更简洁,但只适用于函数输出仅由Series中部分元素决定的场景。

方案三:使用第三方库cachetools(灵活扩展)

如果你愿意安装第三方库,可以用cachetools的cached装饰器,配合自定义的哈希函数来处理Series:

首先安装库:

pip install cachetools

然后实现代码:

from cachetools import cached, LRUCache
import pandas as pd

# 自定义哈希函数:将Series转为元组
def hash_series(series):
    return tuple(series)

@cached(cache=LRUCache(maxsize=None), key=lambda series: hash_series(series))
def fib(n):
    if n.iloc[0] == 1 or n.iloc[0] == 2:
        return 1
    min1 = n.copy()
    min1.iloc[0] -= 1
    min2 = n.copy()
    min2.iloc[0] -= 2
    return fib(min1) + fib(min2)

# 测试调用
print(fib(pd.Series([15, 0])))  # 输出610

这个方案的优势是cachetools提供了更多缓存策略(比如LFU、TTL等),适合复杂场景。

核心原理补充

为什么lru_cache不能直接用?因为Python中只有不可变对象(比如整数、字符串、元组)是可哈希的,而Series是可变容器(你可以随时修改它的元素值),所以默认无法作为缓存的键。我们的解决方案本质都是把可变的Series转换成不可哈希的类型,或者提取其中的不可变部分,让缓存系统能识别重复的参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:29:17