HOWTO · Pandas

Come iterare sulle righe di un DataFrame in Pandas

Confronta i modi per leggere o elaborare le righe in un DataFrame pandas, inclusi df.index, loc[], iloc[], iterrows(), itertuples() e apply().

In questa pagina

Per i calcoli che pandas può esprimere direttamente, preferisci un’operazione vettorializzata; di solito è più semplice ed evita i cicli sulle righe a livello Python. Quando hai bisogno di una logica personalizzata per riga, scegli la selezione basata su etichette o su posizioni, oppure usa un iteratore di righe. Gli esempi usano questa tabella dei redditi; ogni snippet crea il proprio DataFrame in modo da poter essere eseguito in modo indipendente.

import pandas as pd

df = pd.DataFrame({
    "Date": ["April-10", "April-11", "April-12", "April-13", "April-14", "April-16"],
    "Income_1": [10, 20, 10, 15, 10, 12],
    "Income_2": [20, 30, 10, 5, 40, 13],
})

print(df["Income_1"] + df["Income_2"])
0    30
1    50
2    20
3    20
4    50
5    25
dtype: int64

Iterare sulle righe con df.index

df.index contiene le etichette delle righe. Con l’indice predefinito in questo esempio, le etichette vanno da 0 a 5, quindi funzionano anche come etichette in df.loc. Un indice personalizzato o non consecutivo modifica queste etichette; non dare per scontato che siano posizioni di riga.

import pandas as pd

df = pd.DataFrame({
    "Date": ["April-10", "April-11", "April-12", "April-13", "April-14", "April-16"],
    "Income_1": [10, 20, 10, 15, 10, 12],
    "Income_2": [20, 30, 10, 5, 40, 13],
})

for label in df.index:
    row = df.loc[label]
    total = row["Income_1"] + row["Income_2"]
    print(f"Total income in {row['Date']} is: {total}")
Total income in April-10 is: 30
Total income in April-11 is: 50
Total income in April-12 is: 20
Total income in April-13 is: 20
Total income in April-14 is: 50
Total income in April-16 is: 25

Questo legge ogni etichetta, seleziona la sua riga e somma i due valori di reddito. Per un ciclo basato sulla posizione, usa invece iloc[].

Accedere alle righe tramite etichetta con loc[]

Usa loc[] quando il selettore di riga è un’etichetta di indice. Il suo primo selettore sceglie la riga e il secondo sceglie la colonna; le etichette non devono necessariamente essere numeri interi.

import pandas as pd

df = pd.DataFrame({
    "Date": ["April-10", "April-11", "April-12", "April-13", "April-14", "April-16"],
    "Income_1": [10, 20, 10, 15, 10, 12],
    "Income_2": [20, 30, 10, 5, 40, 13],
})

for label in df.index:
    date = df.loc[label, "Date"]
    total = df.loc[label, "Income_1"] + df.loc[label, "Income_2"]
    print(f"Total income in {date} is: {total}")
Total income in April-10 is: 30
Total income in April-11 is: 50
Total income in April-12 is: 20
Total income in April-13 is: 20
Total income in April-14 is: 50
Total income in April-16 is: 25

Iterare su df.index mantiene la ricerca legata alle etichette effettive. Se hai già un’etichetta, puoi selezionare direttamente la sua riga con df.loc[label].

Accedere alle righe tramite posizione con iloc[]

Usa iloc[] quando intendi le posizioni intere: il suo primo selettore è la posizione della riga e il secondo è la posizione della colonna. In questa tabella, le posizioni di colonna 0, 1 e 2 si riferiscono a Date, Income_1 e Income_2.

import pandas as pd

df = pd.DataFrame({
    "Date": ["April-10", "April-11", "April-12", "April-13", "April-14", "April-16"],
    "Income_1": [10, 20, 10, 15, 10, 12],
    "Income_2": [20, 30, 10, 5, 40, 13],
})

for position in range(len(df)):
    date = df.iloc[position, 0]
    total = df.iloc[position, 1] + df.iloc[position, 2]
    print(f"Total income in {date} is: {total}")
Total income in April-10 is: 30
Total income in April-11 is: 50
Total income in April-12 is: 20
Total income in April-13 is: 20
Total income in April-14 is: 50
Total income in April-16 is: 25

A differenza di loc[], iloc[] non interpreta il selettore di riga come un’etichetta di indice. Usalo quando conta l’ordine delle righe.

Iterare con DataFrame.iterrows()

pandas.DataFrame.iterrows() restituisce una coppia per ogni riga: la sua etichetta di indice e la riga come Series. Questo è comodo quando il codice ha bisogno di più colonne denominate, ma può essere più lento dell’iterazione su tuple e può forzare i valori in un dtype di riga comune. Evita di modificare la riga restituita per aggiornare il DataFrame originale.

import pandas as pd

df = pd.DataFrame({
    "Date": ["April-10", "April-11", "April-12", "April-13", "April-14", "April-16"],
    "Income_1": [10, 20, 10, 15, 10, 12],
    "Income_2": [20, 30, 10, 5, 40, 13],
})

for label, row in df.iterrows():
    total = row["Income_1"] + row["Income_2"]
    print(f"Total income in {row['Date']} is: {total}")
Total income in April-10 is: 30
Total income in April-11 is: 50
Total income in April-12 is: 20
Total income in April-13 is: 20
Total income in April-14 is: 50
Total income in April-16 is: 25

L’etichetta è disponibile come label; ai valori della riga si accede tramite il nome della colonna su row.

Iterare con DataFrame.itertuples()

itertuples() restituisce una tupla per riga. Per impostazione predefinita, l’indice è il primo campo della tupla, seguito dai campi per le colonne. Campi denominati come Date e Income_1 rendono questa scelta leggibile per l’elaborazione per riga, e l’iterazione su tuple è spesso preferibile a iterrows() quando l’iterazione è necessaria.

import pandas as pd

df = pd.DataFrame({
    "Date": ["April-10", "April-11", "April-12", "April-13", "April-14", "April-16"],
    "Income_1": [10, 20, 10, 15, 10, 12],
    "Income_2": [20, 30, 10, 5, 40, 13],
})

for row in df.itertuples():
    total = row.Income_1 + row.Income_2
    print(f"Total income in {row.Date} is: {total}")
Total income in April-10 is: 30
Total income in April-11 is: 50
Total income in April-12 is: 20
Total income in April-13 is: 20
Total income in April-14 is: 50
Total income in April-16 is: 25

Per omettere il campo indice, passa index=False; per ricevere tuple ordinarie invece di tuple denominate, passa name=None. I nomi di colonna che non sono identificatori Python validi vengono rinominati nei campi delle tuple denominate, quindi usa le posizioni ordinarie delle tuple o iterrows() quando questo conta.

Applicare una funzione a ogni riga con DataFrame.apply()

DataFrame.apply() può chiamare una funzione una volta per riga con axis=1 (o axis="columns"). Una chiamata per riga restituisce qui una Series, con un risultato per ogni riga di input. Non è la stessa cosa del calcolo vettorializzato e non è automaticamente più veloce di un ciclo; usalo quando l’interfaccia basata su funzioni è utile.

import pandas as pd

df = pd.DataFrame({
    "Date": ["April-10", "April-11", "April-12", "April-13", "April-14", "April-16"],
    "Income_1": [10, 20, 10, 15, 10, 12],
    "Income_2": [20, 30, 10, 5, 40, 13],
})

result = df.apply(
    lambda row: f"Total income in {row['Date']} is: {row['Income_1'] + row['Income_2']}",
    axis=1,
)
print(result.to_string(index=False))
Total income in April-10 is: 30
Total income in April-11 is: 50
Total income in April-12 is: 20
Total income in April-13 is: 20
Total income in April-14 is: 50
Total income in April-16 is: 25

La chiamata restituisce una stringa per riga in result. Per questa semplice addizione, un’espressione vettorializzata come df["Income_1"] + df["Income_2"] è più diretta. Vedi il riferimento a DataFrame.apply() per i parametri del metodo.