Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Elaborazione di DataFrame

Impariamo ad usare i DataFrame di Pandas per analizzare i dati ed usarli all'interno di applicazioni di Machine Learning
Impariamo ad usare i DataFrame di Pandas per analizzare i dati ed usarli all'interno di applicazioni di Machine Learning
Link copiato negli appunti

La flessibilità delle strutture dati di Pandas
rende questa libreria il principale motore per importare ed elaborare dati nella DataScience: qualsiasi operazione ci troveremo a
svolgere nel Machine Learning infatti prenderà tipicamente le mosse o da DataFrame Pandas o da array NumPy.
È importante pertanto imparare a manipolare dati presenti in queste strutture in modo da poter preparare il dataset su cui lavorare
nel modo più confacente ai nostri scopi. In questa lezione, daremo proprio uno sguardo a tecniche di questo genere focalizzate soprattutto
nel produrre dinamicamente nuove colonne.

Creazione di una nuova colonna

I dataset su cui lavoriamo offrono dati forniti da un qualche soggetto per la descrizione di un processo. Molto spesso
è necessario saper creare una nuova colonna che rappresenti l'applicazione di una funzione sui dati in esso presenti e che, ad esempio, potrà
esserci utile per proseguire con un'esplorazione preliminare dello spazio di informazioni. Iniziamo creando
un DataFrame per esercitarci, eccolo:

import pandas as pd  
atleti = {'nome': ['Simone', 'Elena', 'Mario', 'Noemi'],
          'cognome': ['Neri', 'Gialli', 'Rossi', 'Verdi'],
        'eta': [16, 19, 21, 15]}  
squadra = pd.DataFrame(atleti)

La sua forma sarà questa:

nome cognome  eta
0  Simone    Neri   16
1   Elena  Gialli   19
2   Mario   Rossi   21
3   Noemi   Verdi   15

Il DataFrame squadra rappresenta una selezione di atleti molto giovani, non tutti maggiorenni. Supponiamo di voler
vedere a colpo d'occhio, per ogni sportivo, se ha già compiuto 18 anni. Si può fare così:

squadra['eta'] >= 18

ed il risultato sarà una Series (esattamente, pandas.core.series.Series) che avrà questo contenuto:

0    False
1     True
2     True
3    False

Ciò ha prodotto il risultato che ci interessava ma non ha apportato modifiche al DataFrame originale mentre
ciò che vogliamo imparare a fare qui è espandere il DataFrame con colonne create da noi con operazioni di questo tipo. Pandas
rende il tutto facilissimo, sarà infatti sufficiente indicare il nome della nuova colonna ed offrire una regola che determinerà
come questa dovrà essere popolata. Con la direttiva:

squadra['maggiorenne'] = squadra['eta'] >= 18

il DataFrame squadra diventa così:

nome cognome  eta  maggiorenne
0  Simone    Neri   16        False
1   Elena  Gialli   19         True
2   Mario   Rossi   21         True
3   Noemi   Verdi   15        False

dove apparirà una nuova colonna, creata direttamente in virtù dell'assegnazione, che mostrerà i valori
booleani richiesti.

Applicazione di funzioni

Oltre a espressioni di questo genere, si può svolgere la stessa operazione con delle funzioni, eventualmente create
da noi. Supponiamo che ogni atleta debba avere associato anche uno username, diciamo per fare accesso ad un qualche sistema
informatico legato sempre alle attività della squadra e che tale username venga scelto automaticamente usando i primi
due caratteri del nome, i primi due del cognome ed associando il tutto ad un numero casuale di quattro cifre (non ci preoccupiamo qui
di problemi come generazione di eventuali alias o nome/cognome troppo corti). Vogliamo che tale funzione elabori una riga alla
volta il DataFrame ed aggiunga lo username creato in una nuova colonna. Questo il codice che useremo:

def genera_username(riga):
    from random import randint
    return f'{riga.nome[:2].lower()}{riga.cognome[:2].lower()}{randint(1000,9999)}'

Per prima cosa, è fondamentale provarla per essere sicuri di ottenere il comportamento che desideriamo.
Nasce per lavorare su una singola riga del DataFrame (l'argomento in input rappresenta proprio questo) pertanto
faremo una prova con il primo elemento di squadra:

genera_username(squadra.iloc[0])

Otteniamo in risposta lo username sine4439, correttamente prodotto dal nome Simone, il cognome Neri e
l'aggiunta di un numero a quattro cifre. Per creare ora, una nuova colonna come applicazione di tale funzione riga per riga
dobbiamo rivolgerci al metodo apply:

squadra['username']=squadra.apply(genera_username, axis=1)

e squadra conterrà questo (non stupisce che lo username della prima riga sia diverso da quello della prova in quanto
generato in parte casualmente):

nome cognome  eta  maggiorenne  username
0  Simone    Neri   16        False  sine2233
1   Elena  Gialli   19         True  elgi2715
2   Mario   Rossi   21         True  maro1382
3   Noemi   Verdi   15        False  nove3626

Osserviamo bene quanto fatto. Per prima cosa, vediamo che apply ha ricevuto come primo argomento il riferimento
alla funzione da noi creata e come secondo un valore per axis. Quest'ultimo è un parametro fondamentale che specifica
se apply dovrà lavorare per righe o per colonne: axis=1 significa che ogni riga del DataFrame diventa di volta in volta
l'argomento della funzione mentre axis=0 (impostazione di default) cercherebbe di produrre risultati lavorando su ogni singola colonna ma
in questo caso provocherebbe errore.

Elaborazione indipendente di ogni elemento

Infine, esiste un altro metodo, da non confondere con apply, chiamato applymap. La sua particolarità, spesso
utile, consiste nell'applicare una funzione ad ogni elemento del DataFrame. Supponiamo di voler avere un DataFrame in cui in ogni cella
ci sia scritto il tipo di dato del corrispondente elemento di squadra. Ecco come fare:

squadra.applymap(type)

e questo è cosa otteniamo:

nome        cognome            eta     maggiorenne       username
0  <class 'str'>  <class 'str'>  <class 'int'>  <class 'bool'>  <class 'str'>
1  <class 'str'>  <class 'str'>  <class 'int'>  <class 'bool'>  <class 'str'>
2  <class 'str'>  <class 'str'>  <class 'int'>  <class 'bool'>  <class 'str'>
3  <class 'str'>  <class 'str'>  <class 'int'>  <class 'bool'>  <class 'str'>

Al posto di ogni elemento abbiamo l'indicazione del suo tipo di dato (stringa per tutti tranne che per eta e
maggiorenne) ma il DataFrame originale non sarà stato minimamente intaccato infatti il suo contenuto è rimasto il
medesimo:

In [20]: squadra
Out[20]:
     nome cognome  eta  maggiorenne  username
0  Simone    Neri   16        False  sine2233
1   Elena  Gialli   19         True  elgi2715
2   Mario   Rossi   21         True  maro1382
3   Noemi   Verdi   15        False  nove3626

Ti consigliamo anche