In Python puoi definire una funzione in una sola riga, senza darle un nome. Queste funzioni ii chiamano funzioni lambda.
In questa micro-lezione vedremo come usarle con pandas per trasformare dati al volo.
Il programma della micro-lezione
Cosa è una funzione lambda
Una funzione normale in Python si scrive così:
def raddoppia(x):
return x * 2
La versione lambda equivalente è:
raddoppia = lambda x: x * 2
In breve, dopo lambda ci sono i parametri, nel nostro caso x. Dopo i parametri, scrivi l’espressione: ciò che la funzione fa.
Non serve return: il valore dell'espressione viene restituito automaticamente.
Note bene
Una lambda è comoda quando la funzione è breve e la usi una volta sola. Se la logica è complessa o la riutilizzi più volte, è meglio usare una funzione normale con def.
lambda con apply() su una colonna
Per questo esempio useremo un dataframe con i risultati di alcune partite di Serie A.
Costruiamolo al volo:
df = pd.DataFrame({
"in_casa": ["Milan", "Juventus", "Inter", "Napoli", "Roma"],
"ospiti": ["Inter", "Roma", "Napoli", "Milan", "Juventus"],
"spettatori": [74523, 41507, 72456, 51203, 63910],
})
Ed ecco qui il risultato:
in_casa | ospiti | spettatori |
|---|---|---|
Milan | Inter | 74523 |
Juventus | Roma | 41507 |
Inter | Napoli | 72456 |
Napoli | Milan | 51203 |
Roma | Juventus | 63910 |
Immaginiamo di voler formattare i valori degli spettatori del nostro dataframe in una stringa un po’ più leggibile, aggiungendo il separatore delle migliaia.
df["spettatori_fmt"] = (df["spettatori"]
.apply(lambda x: f"{x:,}"
.replace(",", "."))
)Adesso diamo un’occhiata al dataframe:
in_casa | ospiti | spettatori | spettatori_fmt |
|---|---|---|---|
Milan | Inter | 74523 | 74.523 |
Juventus | Roma | 41507 | 41.507 |
Inter | Napoli | 72456 | 72.456 |
Napoli | Milan | 51203 | 51.203 |
Roma | Juventus | 63910 | 63.910 |
In realtà per far sì che il separatore delle migliaia fosse un punto (il che é conforme a ciò che si usa in Italia), abbiamo dovuto introdurre replace().
Infatti, f"{x:,}" applica il separatore delle migliaia, che di default è una virgola. Successivamente, replace() si occupa di sostituire la virgola con una punto.
Usare lambda su più colonne
Per questo esempio, useremo un altro dataframe, leggermente diverso dal precedente.
df2 = pd.DataFrame({
"in_casa": ["Milan", "Juventus", "Inter", "Napoli", "Roma"],
"ospiti": ["Inter", "Roma", "Napoli", "Milan", "Juventus"],
"gol_casa": [2, 0, 2, 4, 1],
"gol_ospiti": [2, 2, 1, 3, 1],
})Ecco qui il nostro nuovo dataframe:
in_casa | ospiti | gol_casa | gol_ospiti |
|---|---|---|---|
Milan | Inter | 2 | 2 |
Juventus | Roma | 0 | 2 |
Inter | Napoli | 2 | 1 |
Napoli | Milan | 4 | 3 |
Roma | Juventus | 1 | 1 |
Adesso costruiamo una funzione lambda per determinare l’esito della partita per la squadra che gioca in casa, partendo dal numero dei gol fatti.
Usando il parametro axis=1 di apply() , la funzione lambda verrà applicata all’intera riga.
In termini pratici, questo vuol dire che l’espressione della funzione lambda può accedere a più colonne.
Vediamo come fare:
df2["esito"] = df2.apply(
lambda riga: "V" if riga["gol_casa"] > riga["gol_ospiti"]
else ("P" if riga["gol_casa"] < riga["gol_ospiti"]
else "N"),
axis=1
)Ed ecco qui il risultato:
in_casa | ospiti | gol_casa | gol_ospiti | esito |
|---|---|---|---|---|
Milan | Inter | 2 | 2 | N |
Juventus | Roma | 0 | 2 | P |
Inter | Napoli | 2 | 1 | V |
Napoli | Milan | 4 | 3 | V |
Roma | Juventus | 1 | 1 | N |
In pratica, avremo V in caso di vittoria della squadra in casa, N in caso di pareggio e P in caso di sconfitta.
Conclusione
Le funzioni lambda non aggiungono funzionalità che non potresti ottenere con una funzione tradizione (quelle che si costruiscono con def) ma rendono il codice più compatto quando la trasformazione è semplice ed ha un contesto ridotto
Alla prossima micro-lezione 👋
Se vuoi imparare la data analysis con micro-lezioni che vanno dritto al sodo, iscriviti alla newsletter: