2014-09-23 15 views
6

Say I setup memoization z Joblib następująco (przy użyciu rozwiązanie przewidziane here):Selektywne Re-memoization z DataFrames

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 

I say I zdefiniować kilka zapytań, query_1 i query_2, oboje potrwać długi czas działania.

Rozumiem, że wraz z kodem, jak to jest:

  • sekund wezwanie albo zapytania, użyłby memoized wyjście, a mianowicie:

    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 
    
  • mogę użyć memory.clear(), aby usunąć cały katalog pamięci podręcznej

Ale co jeśli chcę ponownie wykonać zapamiętywanie dla tylko jednego z zapytań (np. query_2) bez wymuszania usunięcia w drugim zapytaniu?

+4

wydaje się, że [ '.call'] (https://pythonhosted.org/joblib/memory.html#joblib.memory.MemorizedFunc.call) _forces_ obliczeń. możesz sprawdzić, czy to również aktualizuje pamięć podręczną. –

+0

@ behzad.nouri świetny wskaźnik! Miałem nadzieję na taką metodę. Szukałem słowa kluczowego 'force', ale niczego nie znalazłem. '.call' może być odpowiedzią. Sprawdzę to. –

+0

@ behzad.nouri Patrząc na [kod] (https://github.com/joblib/joblib/blob/master/joblib/memory.py#L665-L682), wydaje się, że nazywa się "persist_output", więc myślę, że to da rade! –

Odpowiedz

4

Wygląda na to, że biblioteka nie obsługuje częściowego usuwania pamięci podręcznej.

można oddzielić cache, functino na dwie pary:

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 

Teraz można selektywnie usunąć cache:

memory2.clear() 

UPDATE po obejrzeniu komentarz behzad.nouri za:

Można użyć metody dekorowanej funkcji call. Ale jak widać w poniższym przykładzie, zwracana wartość różni się od normalnego połączenia. Powinieneś się tym zająć.

>>> 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'}}) 
+0

Mam nadzieję, że wykorzystam do uruchomienia dziesiątki zapytań, więc to może nie być skalowalne, ale dzięki, to jest pomocne. –

+1

@ user815423426 Po zapoznaniu się z komentarzem behzad.nouri zaktualizowałem odpowiedź. – falsetru

+0

[Ten komentarz] (https://twitter.com/GaelVaroquaux/status/562735568346689536) od autora dodaje więcej światła do tego. –