代码之家  ›  专栏  ›  技术社区  ›  Jorge Barrios

熊猫系列自变量函数记忆

  •  2
  • Jorge Barrios  · 技术社区  · 6 年前

    我想记忆一个参数可变的函数(熊猫系列对象)。有没有办法做到这一点?

    这里有一个简单的斐波那契例子,参数是熊猫系列,其中第一个元素表示序列的索引。

    示例:

    from functools import lru_cache
    
    @lru_cache(maxsize=None)
    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)
    

    调用函数:

    fib(pd.Series([15,0]))
    

    结果:

    TypeError: 'Series' objects are mutable, thus they cannot be hashed
    

    预期用途更加复杂,因此我发布了这个无用但简单的示例。

    2 回复  |  直到 6 年前
        1
  •  1
  •   Calvin    6 年前

    几个选项:

    • 将可变对象转换为不可变的对象,例如字符串或元组。
    • 创建可变对象的散列,并将其用作备注dict键。哈希冲突的风险。
    • 创建一个实现\uu hash\uuu()函数的不可变子类。
        2
  •  0
  •   Jorge Barrios    6 年前

    我编写了一个包装器,将Pandas系列参数替换为tuple(冻结等价物),正如@abarnert和@Calvin所建议的那样。由于元组是不可变的,因此现在可以对函数进行记忆。

    def freeze_series(f):
        def wrapper(series):
            return f(tuple(series.to_dict(OrderedDict).items()))
        return wrapper
    

    以下是将元组解冻回熊猫系列的常规函数:

    def unfreeze_series(frozen_series):
        return pd.Series(OrderedDict((x, y) for x, y in frozen_series))
    

    可以这样实现来解决问题示例:

    from functools import lru_cache
    
    @freeze_series
    @lru_cache(maxsize=None)
    def fib(n):
        n = unfreeze_series(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)