# DataFrame in Pandas: manipolazione delle tabelle in modo rapido e chiaro in Python

Il DataFrame in Pandas è una struttura dati per Python, utilizzabile per creare e manipolare le tabelle. In questo articolo ti spieghiamo la sintassi di questa struttura dati, oltre ai relativi metodi e alle sue proprietà principali.

## Come funzionano i DataFrame in Pandas?

I DataFrame di Pandas sono l’elemento centrale della libreria [Pandas di Python](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/pandas-di-python/) e consentono di analizzare i dati in modo efficiente e flessibile in Python. Un DataFrame di Pandas è una **struttura di dati bidimensionale e tabellare** contenente **righe numerate e colonne etichettate**. Questa struttura ti permette di organizzare i dati in un formato facile da comprendere e manipolare, simile ai programmi per fogli di calcolo come Excel o [LibreOffice](https://it.libreoffice.org/ "Sito ufficiale di LibreOffice"). Ogni colonna di un DataFrame può contenere diversi [tipi di dati Python](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/tipi-di-dati-in-python/), il che significa che in un DataFrame è possibile salvare **dati eterogenei**, ad esempio valori numerici, sequenze di caratteri e booleani, in un’unica tabella.

Consiglio I DataFrame in Pandas si basano su array NumPy e sono quindi un metodo efficiente per gestire i dati e calcolare i valori. Tuttavia, i DataFrame in Pandas differiscono dalle strutture di dati [NumPy](https://numpy.org/ "Sito ufficiale di NumPy") per alcuni aspetti, ad esempio per la loro eterogeneità e per il loro numero di dimensioni. Per questo motivo, le strutture di dati NumPy sono adatte a manipolare enormi quantità di valori numerici, mentre le strutture di dati Pandas sono più indicate per la manipolazione generale dei dati.

### Struttura dei DataFrame in Pandas

Un DataFrame è costituito da tre componenti principali: i dati stessi, gli indici di riga e i nomi di colonna. L’indice di riga (o semplicemente indice) funge da identificatore univoco per ogni riga. Per impostazione predefinita, le righe sono indicizzate con valori numerici, che però possono essere sostituiti da stringhe. Tieni presente che i DataFrame in Pandas hanno **indicizzazione null**, ossia gli indici partono da 0.

[![Immagine: La struttura di un DataFrame in Pandas](https://www.ionos.it/digitalguide/fileadmin/_processed_/e/9/csm_pandas-dataframe-structure_0ab3bff2f5.webp "La struttura di un DataFrame in Pandas")](https://www.ionos.it/digitalguide/fileadmin/DigitalGuide/Schaubilder/pandas-dataframe-structure.png) I DataFrame in Pandas hanno una struttura tabellare e sono quindi molto simili alle tabelle di Excel o SQL.  N.B. I DataFrame di Pandas sono tra le strutture di dati di Python più utili e apprezzate, ma non fanno parte ufficialmente della dotazione di base di questo linguaggio di programmazione e devono essere sempre **aggiunti a parte**. A tal fine è necessario inserire la riga `import pandas` o `from pandas import DataFrame` all’inizio del file. In alternativa, puoi utilizzare `import pandas as pd` se desideri fare riferimento al modulo con un nome più breve (in questo caso “pd”).

## Come utilizzare i DataFrame in Pandas

I DataFrame in Pandas offrono svariate tecniche e metodi che permettono di modificare, analizzare e visualizzare i dati in modo efficiente. Nei paragrafi seguenti imparerai alcuni dei concetti e dei metodi più importanti per la manipolazione dei dati con i DataFrame in Pandas.

### Creazione di DataFrame in Pandas

Se hai già memorizzato i dati desiderati in una [lista di Python](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/liste-in-python/) o in un [dizionario in Python](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/dizionari-in-python/), puoi creare facilmente un DataFrame partendo da tali dati. A questo scopo non devi far altro che trasferire la struttura di dati esistente, come argomento, al costruttore DataFrame `pandas.DataFrame([Dati])`. Tuttavia, il modo in cui Pandas interpreta i tuoi dati dipende dalla struttura di dati che trasmetti al costruttore. Di seguito ti mostriamo un esempio di come creare un DataFrame in Pandas partendo da un elenco in Python:

```python
import pandas
elenco = ["Alberto", "Beatrice", "Carla", "Diego", "Elisabetta", "Franco"]
df = pandas.DataFrame(elenco)
print(df)
# Risultato:
#            0
# 0     Alberto
# 1      Beatrice
# 2     Carla
# 3    Diego
# 4    Elisabetta
# 5  Franco
```

Come puoi notare nell’esempio sopra, con elenchi semplici è possibile creare solo DataFrame con **una singola colonna non etichettata**. Per questo motivo è consigliabile creare i DataFrame partendo da **dizionari che contengono gli elenchi**. In questo modo, le chiavi vengono interpretate come nomi delle colonne e gli elenchi come i dati a esse correlati. Per chiarire il funzionamento, osserva l’esempio seguente:

```python
import pandas
dati = {
    'Nome': ['Arturo', 'Bruno', 'Cristiano'],
    'Età': [34, 30, 55],
    'Stipendio': [75000.0, 60000.5, 90000.3],
}
df = pandas.DataFrame(dati)
print(df)
# Risultato:
#         Nome  Età   Stipendio
# 0     Arturo     34  75000.0
# 1      Bruno     30  60000.5
# 2  Cristiano     55  90000.3
```

Con questo metodo il DataFrame acquisisce immediatamente il formato e i titoli che desideri. Se invece non vuoi appoggiarti alle strutture di dati integrate in Python, puoi anche **caricare i tuoi dati da una fonte esterna**, ad esempio da un file CSV o da un database [SQL](https://www.ionos.it/digitalguide/server/know-how/che-cose-sql/). A tal fine è sufficiente richiamare l’apposita funzione di Pandas:

```python
import pandas
import sqlalchemy
# DataFrame da CSV:
csv = pandas.read_csv("file-csv/dati.csv")
# DataFrame da SQL:
engine = create_engine('postgresql://nomeutente:password@localhost:5432/mio_database')
sql = pandas.read_sql_query('SELECT * FROM tabella', engine)
```

I DataFrame `csv` e `sql` dell’esempio precedente contengono ora tutti i dati del file `dati.csv` e della tabella SQL `tabella`. In più, è possibile specificare ulteriori dettagli durante la creazione di un DataFrame partendo da una fonte esterna, ad esempio scegliendo se includere o meno gli indici numerici nel DataFrame. Per ulteriori informazioni sugli argomenti aggiuntivi delle due funzioni consulta la [pagina ufficiale per i DataFrame in Pandas](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html "DataFrame in Pandas").

Consiglio Per creare un DataFrame in Pandas partendo da una tabella SQL è necessario utilizzare Pandas insieme a un modulo SQL Python come *SQLAlchemy*. A tal fine, crea una connessione al database utilizzando il modulo SQL scelto e passala a `read_sql_query()`.

### DataFrame in Pandas: visualizzazione dei dati

Con i DataFrame in Pandas puoi visualizzare non soltanto l’intera tabella, ma anche singole righe e colonne. In più, puoi scegliere le righe e le colonne da visualizzare. L’esempio seguente mostra come visualizzare righe o colonne singole o multiple:

```python
# Mostra la riga 0
print(df.loc[0])
# Mostra righe da 3 a 6
print(df.loc[3:6])
# Mostra righe da 3 e 6
print(df.loc[[3, 6]])
# Mostra colonna “Professione”
print(df["Professione"])
# Mostra colonne “Professione” e “Età”
print(df[["Professione", "Età"]])
# Selezione di più righe e colonne
print(df.loc[[3, 6], ['Professione', 'Età']])
```

Come puoi notare nell’esempio, facendo riferimento a una colonna si utilizza soltanto il nome della colonna stessa tra parentesi semplici, come nei dizionari Python. Al contrario, quando si fa riferimento a una riga si utilizza sempre l’attributo `loc`. Con `loc` è possibile anche usare condizioni logiche per filtrare i dati. Questa alternativa è utilizzata nel seguente blocco di codice, che stampa solo le righe in cui il valore “Età” è maggiore di 30:

```python
print(df.loc[df['Età'] > 30])
```

Inoltre, è possibile utilizzare l’attributo `iloc` per selezionare righe e colonne **in base alla loro posizione nel DataFrame**. In questo modo, ad esempio, puoi visualizzare la cella nella terza riga della quarta colonna:

```python
print(df.iloc[3, 4])
# Risultato:
# Torino
print(df.iloc[[3, 4, 6], 4])
# Risultato:
# 3    Torino
# 4    Milano
# 6    Venezia
```

### DataFrame in Pandas: iterazione sulle righe

Quando si manipolano i dati in Python, spesso è necessario eseguire iterazioni sulle righe di un DataFrame in Pandas, ad esempio per applicare la stessa operazione su tutti i dati. A tal fine, Pandas offre due diversi metodi per DataFrame: `itertuples()` e `iterrows()`. Entrambi i metodi presentano vantaggi e svantaggi in termini di **prestazioni e facilità d’uso**.

Il metodo `iterrows()` restituisce una **tupla composta da indice e serie** per ciascuna riga del DataFrame. Una serie è un’altra struttura dati di Pandas o NumPy che è molto simile a una lista di Python in molti aspetti, ma che offre prestazioni migliori. È possibile accedere ai singoli elementi della serie utilizzando il **nome della colonna**, il che semplifica molto la gestione dei dati.

Sebbene le serie di Pandas siano di gran lunga più efficienti delle liste di Python, questa struttura di dati presenta comunque un notevole overhead in termini di prestazioni. Per questo motivo è particolarmente consigliato il metodo `itertuples()` per i **DataFrame molto grandi**. A differenza di `iterrows()`, il metodo `itertuples()` restituisce **l’intera riga compreso l’indice** sotto forma di tuple, che offrono prestazioni molto superiori rispetto alle serie. Le tuple permettono di accedere ai singoli elementi utilizzando un punto, come nel caso degli attributi di un oggetto.

Un’altra importante differenza tra serie e tuple è che **le tuple non sono mutabili**. Pertanto, se desideri eseguire un’iterazione su un DataFrame e modificare i valori utilizzando `itertuples()`, devi fare riferimento al DataFrame usando l’attributo `at` e l’indice della tupla. Questo attributo funziona in modo molto simile a `loc`. L’esempio seguente mostra le differenze tra `iterrows()` e `itertuples()`:

```python
import pandas
df = pandas.DataFrame({
    'Nome': ['Alice', 'Bruno', 'Carlo],
    'Età': [25, 30, 35],
    'Stipendio': [70000.0, 80000.5, 90000.3]
})
for index, row in df.iterrows():
        row['Stipendio'] += 1000
        print(f"Index: {index}, Età: {row['Età']}, Stipendio: {row['Stipendio']}")
for tup in df.itertuples():
        df.at[tup.Index, 'Stipendio'] += 1000 # Modifica valore tramite at[] direttamente nel DataFrame
        print(f"Index: {tup.Index}, Età: {tup.Età}, Stipendio: {df.loc[tup.Index, 'Stipendio']}")
# Entrambi i cicli danno lo stesso risultato
```


This is a markdown version of: [https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/dataframe-in-pandas-per-python/](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/dataframe-in-pandas-per-python/) for AI/LLM consumption.