Выборочная повторная память фреймов данных

Скажем, я настраиваю мемоизацию с помощью Joblib следующим образом. (используя решение, предоставленное здесь):

from tempfile import mkdtemp
cachedir = mkdtemp()

from joblib import Memory
memory = Memory(cachedir=cachedir, verbose=0)

@memory.cache
def run_my_query(my_query)
    ...
    return df

И скажем, я определяю пару запросов, query_1 и query_2, оба они выполняются долго.

Я понимаю, что с кодом как есть:

  • Второй вызов с любым запросом будет использовать мемоизированный вывод, т. е.:

    run_my_query(query_1)
    run_my_query(query_1) # <- Uses cached output
    
    run_my_query(query_2)
    run_my_query(query_2) # <- Uses cached output   
    
  • Я мог бы использовать memory.clear() для удаления всего каталога кеша

Но что, если я хочу повторно выполнить запоминание для только одного из запросов (например, query_2) без принудительного удаления другого запроса?


person Amelio Vazquez-Reina    schedule 23.09.2014    source источник
comment
кажется, что .call принуждает вычисление. вы можете проверить, обновляет ли он кеш.   -  person behzad.nouri    schedule 23.09.2014
comment
@behzad.nouri отличный указатель! Я надеялся на такой метод. Я искал ключевое слово force, но ничего не нашел. .call может быть ответом. Я проверю.   -  person Amelio Vazquez-Reina    schedule 23.09.2014
comment
@behzad.nouri Глядя на код , кажется, вызывает persist_output, так что я думаю, что это сработает!   -  person Amelio Vazquez-Reina    schedule 23.09.2014


Ответы (1)


Похоже библиотека не поддерживает частичную очистку кеша.

Вы можете разделить кеш, functino на две пары:

from tempfile import mkdtemp
from joblib import Memory

memory1 = Memory(cachedir=mkdtemp(), verbose=0)
memory2 = Memory(cachedir=mkdtemp(), verbose=0)

@memory1.cache
def run_my_query1()
    # run query_1
    return df

@memory2.cache
def run_my_query2()
    # run query_2
    return df

Теперь вы можете выборочно очистить кеш:

memory2.clear()

ОБНОВЛЕНИЕ после просмотра комментария behzad.nouri:

Вы можете использовать метод call декорированной функции. Но, как вы можете видеть в следующем примере, возвращаемое значение отличается от обычного вызова. Вы должны позаботиться об этом.

>>> import tempfile
>>> import joblib
>>> memory = joblib.Memory(cachedir=tempfile.mkdtemp(), verbose=0)
>>> @memory.cache
... def run(x):
...     print('called with {}'.format(x))  # for debug
...     return x
...
>>> run(1)
called with 1
1
>>> run(2)
called with 2
2
>>> run(3)
called with 3
3
>>> run(2)  # Cached
2
>>> run.call(2)  # Force call of the original function
called with 2
(2, {'duration': 0.0011069774627685547, 'input_args': {'x': '2'}})
person falsetru    schedule 23.09.2014
comment
Я надеюсь использовать запуск десятков запросов, так что это может не масштабироваться, но спасибо, это полезно. - person Amelio Vazquez-Reina; 23.09.2014
comment
@ user815423426, увидев комментарий behzad.nouri, я обновил ответ. - person falsetru; 23.09.2014
comment
Этот комментарий от автора проливает свет на это. - person Amelio Vazquez-Reina; 04.02.2015