2016-04-13 8 views
6

Se ho una funzioneRun funzione una sola volta per ogni riga in un dataframe Pandas

def do_irreversible_thing(a, b): 
    print a, b 

E un dataframe, dire

df = pd.DataFrame([(0, 1), (2, 3), (4, 5)], columns=['a', 'b']) 

Qual è il modo migliore per eseguire la funzione esattamente una volta per ogni riga in un dataframe panda. As indicato in altri questions, qualcosa come pf.apply chiamerà la funzione due volte per la prima riga. Anche usando NumPy

np.vectorize(do_irreversible_thing)(df.a, df.b) 

causa la funzione di essere chiamato due volte sulla prima fila, così come df.T.apply() o df.apply (..., asse = 1).

Esiste un modo più rapido o più semplice per chiamare la funzione con ogni riga rispetto a questo ciclo esplicito?

for idx, a, b in df.itertuples(): 
     do_irreversible_thing(a, b) 
+3

volontà non 'df.apply (lambda x: do_irreversible_thing (x [ 'a'] , x ['b']), axis = 1) 'lavoro? inoltre l'idea è di usare metodi vettorizzati nella tua funzione in modo che operi sulle colonne dell'interesse. – EdChum

+0

Sembra un lavoro per un ciclo 'for'. In genere non è un buon modo per vettorializzare gli effetti collaterali. – user2357112

+0

Se gli effetti collaterali non dipendono dall'operazione per ogni riga, allora dovrebbe essere vettorizzabile – EdChum

risposta

2

Non è chiaro quello che fa la funzione, ma per apply una funzione per ogni riga è possibile farlo passando axis=1 al apply la funzione row-wise e superare gli elementi delle colonne di interesse:

In [155]: 
def foo(a,b): 
    return a*b 
​ 
df = pd.DataFrame([(0, 1), (2, 3), (4, 5)], columns=['a', 'b']) 
df.apply(lambda x: foo(x['a'], x['b']), axis=1) 

Out[155]: 
0  0 
1  6 
2 20 
dtype: int64 

Tuttavia, fino a quando la funzione non dipende il df mutazione su ogni riga, allora si può solo utilizzare un metodo Vectorised di operare su tutta la colonna:

In [156]: 
df['a'] * df['b'] 

Out[156]: 
0  0 
1  6 
2 20 
dtype: int64 

La ragione è che, poiché le funzioni sono vettorizzati allora sarà scalare meglio mentre il apply è lo zucchero sintattico per iterare sul df quindi è un ciclo for essenzialmente

2

Il modo in cui lo faccio (perché anche io non lo faccio come l'idea di looping con df.itertuples) è:

df.apply(do_irreversible_thing, axis=1) 

e quindi la funzione dovrebbe essere come:

def do_irreversible_thing(x): 
    print x.a, x.b 

questo modo si dovrebbe essere in grado di eseguire la funzione su ogni riga.

O

se non è possibile modificare la funzione si potrebbe apply in questo modo

df.apply(lambda x: do_irreversible_thing(x[0],x[1]), axis=1) 
Problemi correlati