【问题标题】:Pandas Series argument function memoizationPandas 系列参数函数记忆
【发布时间】:2018-03-17 20:24:34
【问题描述】:

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

这是一个简单的斐波那契示例,参数是 Pandas Series,其中第一个元素表示序列的索引。

例子:

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

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

【问题讨论】:

  • 我们可以看看你的代码吗?
  • 您的问题是什么?为什么不能散列可变值?
  • 另外,如果您希望通过相等性对某些可变字段进行记忆,但您知道在缓存的生命周期内不会改变它们,所以没关系,您需要“冻结”这些字段——例如,将一个列表复制到一个元组中,或者在类中创建一个不安全但有用的__hash__ 方法(或者一个具有用于冻结实例的 API 的安全方法,以便在冻结之前对其进行哈希处理)等.
  • 我怀疑您的下一个问题将是如何有效且简单地创建与 Pandas 系列相同的冻结版本……我不知道答案,但您可能想四处搜索如果找不到答案,请提出具体问题。
  • 您显然可以通过使用 freeze-series-holder 包装系列来做到这一点,该系列在构造时手动计算哈希,例如,散列值的元组的元组,然后使用这些持有者无处不在,但可能有更简单的方法。

标签: python pandas memoization mutable


【解决方案1】:

几个选项:

  • 将可变对象转换为不可变对象,例如字符串或元组。
  • 创建可变对象的哈希并将其用作备忘录字典键。哈希冲突的风险。
  • 创建一个实现 __hash__() 函数的不可变子类。

【讨论】:

    【解决方案2】:

    我编写了一个包装器,用 @abarnert 和 @Calvin 建议的元组(冻结等效项)替换 Pandas Series 参数。由于元组是不可变的,因此现在可以记忆该函数。

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

    这是一个将元组解冻为 Pandas 系列的普通函数:

    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)
    

    【讨论】:

      猜你喜欢
      • 2015-03-20
      • 2013-08-20
      • 2014-06-02
      • 2010-10-12
      • 2010-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-04
      相关资源
      最近更新 更多