python panda: applica una funzione con argomenti a una serie


147

Voglio applicare una funzione con argomenti a una serie in python panda:

x = my_series.apply(my_function, more_arguments_1)
y = my_series.apply(my_function, more_arguments_2)
...

La documentazione descrive il supporto per un metodo apply, ma non accetta alcun argomento. Esiste un metodo diverso che accetta argomenti? In alternativa, mi sto perdendo una semplice soluzione?

Aggiornamento (ottobre 2017): da quando questa domanda è stata originariamente posta, Panda apply()è stato aggiornato per gestire gli argomenti posizionali e delle parole chiave e il collegamento di documentazione sopra ora riflette ciò e mostra come includere entrambi i tipi di argomento.


3
Perché non usare semplicemente functools.partialo starmap?
Joel Cornett,

Risposte:


170

Le versioni più recenti di Panda ti permettono di passare argomenti extra (vedi la nuova documentazione ). Quindi ora puoi fare:

my_series.apply(your_function, args=(2,3,4), extra_kw=1)

Gli argomenti posizionali vengono aggiunti dopo l'elemento della serie.


Per la versione precedente di Panda:

La documentazione lo spiega chiaramente. Il metodo apply accetta una funzione python che dovrebbe avere un singolo parametro. Se vuoi passare più parametri, dovresti usare functools.partialcome suggerito da Joel Cornett nel suo commento.

Un esempio:

>>> import functools
>>> import operator
>>> add_3 = functools.partial(operator.add,3)
>>> add_3(2)
5
>>> add_3(7)
10

Puoi anche passare argomenti per parole chiave usando partial.

Un altro modo sarebbe quello di creare una lambda:

my_series.apply((lambda x: your_func(a,b,c,d,...,x)))

Ma penso che usare partialsia meglio.


12
Per un metodo di applicazione DataFrame accetta l' argsargomento, che è una tupla contenente argomenti posizionali aggiuntivi o ** kwds per quelli con nome. Ho creato un problema per avere questo anche per Series.apply () github.com/pydata/pandas/issues/1829
Wouter Overmeire

28
La funzionalità è stata implementata, sarà nella prossima uscita dei panda
Wes McKinney,

4
Questa è una bella risposta, ma i primi 2/3 sono davvero obsoleti ora. IMO, questa risposta potrebbe essere ben aggiornata semplicemente essendo un collegamento alla nuova documentazione più un breve esempio di come usare con argomenti di posizione e / o parola chiave. Solo FWIW e non una critica alla risposta originale, trarrebbero beneficio da un aggiornamento IMO, soprattutto perché è una risposta frequentemente letta.
Giovanni,

@watsonic Da allora la documentazione è stata aggiornata e facendo clic sui vecchi collegamenti si accede alla documentazione corrente che ora risponde molto bene alla domanda.
Giovanni,

Nota: se si sta passando un singolo argomento stringa, ad esempio 'abc', args=('abc')verrà valutato come tre argomenti ('a', 'b', 'c'). Per evitarlo, devi passare una tupla contenente la stringa e, per farlo, includi una virgola finale:args=('abc',)
Rocky K

82

passi:

  1. Crea un frame di dati
  2. Crea una funzione
  3. Utilizzare gli argomenti nominati della funzione nell'istruzione apply.

Esempio

x=pd.DataFrame([1,2,3,4])  

def add(i1, i2):  
    return i1+i2

x.apply(add,i2=9)

Il risultato di questo esempio è che ogni numero nel frame di dati verrà aggiunto al numero 9.

    0
0  10
1  11
2  12
3  13

Spiegazione:

La funzione "aggiungi" ha due parametri: i1, i2. Il primo parametro sarà il valore nel frame di dati e il secondo è qualunque cosa passiamo alla funzione "applica". In questo caso, stiamo passando "9" alla funzione apply utilizzando l'argomento della parola chiave "i2".


2
Esattamente quello che stavo cercando. In particolare, ciò non richiede la creazione di una funzione personalizzata solo per gestire una serie (o df). Perfetto!
Connor

L'unica domanda rimanente è: come passare un argomento di parole chiave al primo argomento in add (i1) e iterare con i2?
Connor

Penso che questa sia la migliore risposta
criptoval

43
Series.apply(func, convert_dtype=True, args=(), **kwds)

args : tuple

x = my_series.apply(my_function, args = (arg1,))

11
Grazie! Puoi spiegare perché args = (arg1,) ha bisogno di una virgola dopo il primo argomento?
DrMisha,

21
@MishaTeplitskiy, hai bisogno della virgola affinché Python capisca che il contenuto delle parentesi è una tupla di lunghezza 1.
Prooffreader

3
Che dire di mettere in discussione per il func. Quindi, se desidero applicare pd.Series.mean(axis=1)come inserisco il axis=1?
Tavolini Bobby

1
Come nota a margine, puoi anche aggiungere un argomento di parole chiave senza utilizzare il parametro <args> (ad esempio: x = my_series.apply (my_function, keyword_arg = arg1), dove <keyword_arg> è tra i parametri di input di my_function)
lev

1
questa risposta è troppo breve e non spiega nulla
FistOfFury

23

È possibile passare un numero qualsiasi di argomenti alla funzione che applychiama tramite argomenti senza nome, passati come tupla al argsparametro o tramite altri argomenti di parole chiave catturati internamente come dizionario dal kwdsparametro.

Ad esempio, costruiamo una funzione che restituisca True per valori compresi tra 3 e 6 e False in caso contrario.

s = pd.Series(np.random.randint(0,10, 10))
s

0    5
1    3
2    1
3    1
4    6
5    0
6    3
7    4
8    9
9    6
dtype: int64

s.apply(lambda x: x >= 3 and x <= 6)

0     True
1     True
2    False
3    False
4     True
5    False
6     True
7     True
8    False
9     True
dtype: bool

Questa funzione anonima non è molto flessibile. Creiamo una normale funzione con due argomenti per controllare i valori minimo e massimo desiderati nella nostra serie.

def between(x, low, high):
    return x >= low and x =< high

Possiamo replicare l'output della prima funzione passando argomenti senza nome a args:

s.apply(between, args=(3,6))

Oppure possiamo usare gli argomenti nominati

s.apply(between, low=3, high=6)

O anche una combinazione di entrambi

s.apply(between, args=(3,), high=6)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.