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.