2016-06-22 37 views
10

Ho il seguente problemacome parallelizzare molti confronti di stringa (fuzzy) usando apply in Panda?

Ho un dataframe maestro che contiene frasi, come ad esempio

master 
Out[8]: 
        original 
0 this is a nice sentence 
1  this is another one 
2 stackoverflow is nice 

Per ogni riga in Master, io di ricerca in un altro dataframe schiavo per la migliore corrispondenza con fuzzywuzzy. Io uso fuzzywuzzy perché le frasi corrispondenti tra i due dataframes potrebbero differire un po '(caratteri extra, ecc.).

Per esempio, schiavo potrebbe essere

slave 
Out[10]: 
    my_value      name 
0   2    hello world 
1   1   congratulations 
2   2 this is a nice sentence 
3   3  this is another one 
4   1  stackoverflow is nice 

Ecco una completamente funzionale, meraviglioso, compatto esempio di lavoro :)

from fuzzywuzzy import fuzz 
import pandas as pd 
import numpy as np 
import difflib 


master= pd.DataFrame({'original':['this is a nice sentence', 
'this is another one', 
'stackoverflow is nice']}) 


slave= pd.DataFrame({'name':['hello world', 
'congratulations', 
'this is a nice sentence ', 
'this is another one', 
'stackoverflow is nice'],'my_value': [2,1,2,3,1]}) 

def fuzzy_score(str1, str2): 
    return fuzz.token_set_ratio(str1, str2) 

def helper(orig_string, slave_df): 
    #use fuzzywuzzy to see how close original and name are 
    slave_df['score'] = slave_df.name.apply(lambda x: fuzzy_score(x,orig_string)) 
    #return my_value corresponding to the highest score 
    return slave_df.ix[slave_df.score.idxmax(),'my_value'] 

master['my_value'] = master.original.apply(lambda x: helper(x,slave)) 

la questione di 1 milione di dollari è: posso parallelizzare il mio codice di applicazione sopra?

Dopo tutto, ogni riga master viene confrontata con tutte le righe slave (slave è un piccolo insieme di dati e può contenere molte copie dei dati nella RAM).

Non vedo perché non è stato possibile eseguire più confronti (ad esempio, elaborare più righe contemporaneamente).

Problema: non so come farlo o se è possibile.

Qualsiasi aiuto molto apprezzato!

+1

Ho notato che hai aggiunto il tag dask qui. Hai già provato a usare dask e hai riscontrato un problema? – MRocklin

+0

grazie per il vostro aiuto! sembra che dask accetti solo le funzioni regolari –

+0

inoltre, ho solo un computer quindi nessun lavoro distribuito tra le macchine –

risposta

19

È possibile parallelizzare questo con Dask.dataframe. Ciò funzionerà quasi lo stesso, tranne che non è possibile utilizzare l'assegnazione colonna e sarà invece necessario utilizzare il metodo assign

>>> dmaster = dd.from_pandas(master, npartitions=4) 
>>> dmaster = dmaster.assign(my_value=dmaster.original.apply(lambda x: helper(x, slave), name='my_value')) 
>>> dmaster.compute() 
        original my_value 
0 this is a nice sentence   2 
1  this is another one   3 
2 stackoverflow is nice   1 

Inoltre, si dovrebbe pensare ai compromessi tra utilizzando thread vs processi qui. Quasi certamente la corrispondenza con le stringhe fuzzy non rilascia GIL, quindi non otterrai alcun beneficio dall'utilizzo di più thread. Tuttavia, l'utilizzo dei processi farà sì che i dati vengano serializzati e spostati all'interno della macchina, il che potrebbe rallentare un po 'le cose.

È possibile sperimentare tra l'utilizzo di thread e processi o un sistema distribuito gestendo l'argomento parola chiave get= nel metodo compute().

import dask.multiprocessing 
import dask.threaded 

>>> dmaster.compute(get=dask.threaded.get) # this is default for dask.dataframe 
>>> dmaster.compute(get=dask.multiprocessing.get) # try processes instead 
+0

genio! solo una rapida domanda: ho una macchina xeon a 8 core, funzionerà su di essa? Non è possibile utilizzare un sistema distribuito come suggerito –

+1

La multiprocessing accelererà i calcoli ma rallenterà dal trasferimento dei dati tra processi. Non c'è modo per me di sapere se le cose si accelereranno o meno senza sapere molto più del tuo problema di quanto io voglia davvero entrare. Vi consiglio di provarlo e profilarlo. – MRocklin

+0

grazie @MRocklin! Sono sicuro che molti troveranno utile questo post. Io stesso, ero ancora completamente all'oscuro di 'dask' dopo aver sfogliato il http://dask.pydata.org/en/latest/install.html –