【问题标题】:Hashable Pandas DatetimeIndex可散列的 Pandas 日期时间索引
【发布时间】:2017-10-18 15:13:39
【问题描述】:

我正在尝试使用 @functools.lru_cache() 注释来记忆方法 foo(dti: DatetimeIndex)。但是,它向TypeError: unhashable type: 'DatetimeIndex' 抱怨。

既然DatetimeIndex 对象是不可变的,那么应该有一种很好的方法可以将它们用作记忆的键,对吧?

另外,DatetimeIndex 定义一个哈希方法来简单地返回它的id() 会有什么问题?

【问题讨论】:

  • 不是“记忆”,记忆。见en.wikipedia.org/wiki/Memoization
  • 我想缓存它只是因为计算 foo 很昂贵。在我的情况下,这是一个本质上昂贵的操作,我几乎无法让它更快。
  • 是的,是的,否则我不会寻找解决方案。我不知道你为什么怀疑它。举个例子:假设用户可以交互输入任意整数,我们想要对每个整数进行质数分解。除非您缓存先前分解的输出,否则无法避免返工。就是这样的情况 - 我不知道我会看到什么 DatetimeIndex 值,但我想避免重做我最近已经完成的工作。
  • 不,它需要查看整个DatetimeIndex 对象。它是整个对象的函数。
  • 对不起@MaxU,但这已经是我想问的确切问题,我真的不明白为什么你认为它定义不明确或不应该问。问题是关于 DatetimeIndex 对象的记忆和散列,而不是我是否可以优化其他一些不讨论的调用代码。

标签: python pandas hash memoization datetimeindex


【解决方案1】:

我最终编写了自己的装饰器,以便能够记住接受DataFrame 对象(或Hashable 对象,以防DataFrames 将来可散列)的方法,它看起来像这样:

def my_memoize(func):
    # TODO use an LRU cache so we don't grow forever
    cache = {}

    def decorating_function(self, arg):
        key = arg if isinstance(arg, collections.Hashable) else id(arg)
        key = (self, key)
        if key in cache:
            return cache[key]
        value = func(self, arg)
        cache[key] = value
        return value

    return decorating_function

我是这样使用的:

@my_memoize
def calculate_stuff(self, df):
    ...

【讨论】:

  • 如果一个 DatetimeIndex 被释放并且随后在相同的内存地址分配了一个新的、非等效的索引,这将返回一个不正确的结果。使用 id() 作为缓存键的一部分的问题在于,它不能保证具有非重叠生命周期的对象的唯一性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-16
  • 2012-08-24
  • 1970-01-01
  • 2019-06-22
  • 2017-08-13
  • 2018-05-15
相关资源
最近更新 更多