
Se pandas.DataFrame viene passato dal ciclo per così com’è, vengono restituiti i nomi delle colonne. Puoi scorrere colonne e righe di pandas.DataFrame con i metodi iteritemi(), iterrows() e itertuple().
In questo articolo vengono descritti i seguenti contenuti.
- Iterare pandas.DataFrame nel ciclo per così com’è
- Iterare le colonne di pandas.DataFrame
- Iterare le righe di pandas.DataFrame
- DataFrame.iterrows()
- DataFrame.itertuples()
- Iterare solo colonne specifiche
- Aggiorna i valori nel ciclo per
- Confronto di velocità
Per ulteriori informazioni sull’istruzione per in Python, vedere l’articolo seguente.
Usa il seguente pandas.DataFrame come esempio.
import pandas as pd
import numpy as np
df = pd.DataFrame({'age': [24, 42], 'state': ['NY', 'CA'], 'point': [64, 92]},
index=['Alice', 'Bob'])
print(df)
# age state point
# Alice 24 NY 64
# Bob 42 CA 92
Iterare pandas.DataFrame nel ciclo per così com’è
Se ripeti pandas.DataFrame in un ciclo per così com’è, i nomi delle colonne vengono restituiti in ordine.
for column_name in df:
print(column_name)
# age
# state
# point
Iterare le colonne di pandas.DataFrame
DataFrame.iteritems()
Il metodo sulle iteritems() scorre sulle colonne e riporta (nome colonna, serie), una tupla con il nome della colonna e il contenuto come pandas.Series.
for column_name, item in df.iteritems():
print(column_name)
print('------')
print(type(item))
print(item)
print('------')
print(item[0], item['Alice'], item.Alice)
print(item[1], item['Bob'], item.Bob)
print('======n')
# age
# ------
# <class 'pandas.core.series.Series'>
# Alice 24
# Bob 42
# Name: age, dtype: int64
# ------
# 24 24 24
# 42 42 42
# ======
#
# state
# ------
# <class 'pandas.core.series.Series'>
# Alice NY
# Bob CA
# Name: state, dtype: object
# ------
# NY NY NY
# CA CA CA
# ======
#
# point
# ------
# <class 'pandas.core.series.Series'>
# Alice 64
# Bob 92
# Name: point, dtype: int64
# ------
# 64 64 64
# 92 92 92
# ======
#
Iterare le righe di pandas.DataFrame
I metodi iterrows() e itertules() eseguono l’iterazione sulle righe. Il metodo itertuples() è più veloce.
Se sono necessari solo i valori per una determinata colonna, è ancora più veloce scorrere gli elementi di una determinata colonna individualmente, come spiegato di seguito. I risultati del confronto di velocità sono mostrati alla fine.
DataFrame.iterrows()
Il metodo iterrows() scorre su righe e restituisce (indice, serie), una tupla con l’indice e il contenuto come pandas.Series.
for index, row in df.iterrows():
print(index)
print('------')
print(type(row))
print(row)
print('------')
print(row[0], row['age'], row.age)
print(row[1], row['state'], row.state)
print(row[2], row['point'], row.point)
print('======n')
# Alice
# ------
# <class 'pandas.core.series.Series'>
# age 24
# state NY
# point 64
# Name: Alice, dtype: object
# ------
# 24 24 24
# NY NY NY
# 64 64 64
# ======
#
# Bob
# ------
# <class 'pandas.core.series.Series'>
# age 42
# state CA
# point 92
# Name: Bob, dtype: object
# ------
# 42 42 42
# CA CA CA
# 92 92 92
# ======
#
DataFrame.itertuples()
Il metodo sulle righe itertuples() scorre e restituisce una tupla dell’indice e del contenuto. Il primo elemento della tupla è l’indice.
Per definizione predefinita, restituisce una tupla denominata Pandas. Poiché è una namedtuple, puoi accedere al valore di ogni elemento tramite . così vieni [].
for row in df.itertuples():
print(type(row))
print(row)
print('------')
print(row[0], row.Index)
print(row[1], row.age)
print(row[2], row.state)
print(row[3], row.point)
print('======n')
# <class 'pandas.core.frame.Pandas'>
# Pandas(Index='Alice', age=24, state="NY", point=64)
# ------
# Alice Alice
# 24 24
# NY NY
# 64 64
# ======
#
# <class 'pandas.core.frame.Pandas'>
# Pandas(Index='Bob', age=42, state="CA", point=92)
# ------
# Bob Bob
# 42 42
# CA CA
# 92 92
# ======
#
Viene restituita una tupla normale se il parametro viene impostato su None.
for row in df.itertuples(name=None):
print(type(row))
print(row)
print(row[0], row[1], row[2], row[3])
print('======n')
# <class 'tuple'>
# ('Alice', 24, 'NY', 64)
# Alice 24 NY 64
# ======
#
# <class 'tuple'>
# ('Bob', 42, 'CA', 92)
# Bob 42 CA 92
# ======
#
Iterare solo colonne specifiche
Se hai bisogno solo degli elementi di una particolare colonna, puoi anche scrivere come segue.
La colonna pandas.DataFrame è pandas.Series.
print(df['age'])
# Alice 24
# Bob 42
# Name: age, dtype: int64
print(type(df['age']))
# <class 'pandas.core.series.Series'>
Se applichi pandas.Series a un ciclo for, puoi ottenere i suoi valori in ordine. Puoi ottenere i valori di quella colonna in ordine specificando una colonna di pandas.DataFrame e applicandola a un ciclo for.
for age in df['age']:
print(age)
# 24
# 42
Puoi anche ottenere i valori di più colonne con la funzione zip() incorporata.
for age, point in zip(df['age'], df['point']):
print(age, point)
# 24 64
# 42 92
Utilizzare l’attributo index se si desidera ottenere l’indice. Vieni nell’esempio sopra, puoi metterlo insieme ad altre colonne tramite zip().
print(df.index)
# Index(['Alice', 'Bob'], dtype="object")
print(type(df.index))
# <class 'pandas.core.indexes.base.Index'>
for index in df.index:
print(index)
# Alice
# Bob
for index, state in zip(df.index, df['state']):
print(index, state)
# Alice NY
# Bob CA
Aggiorna i valori nel ciclo per
Il pandas.Series restituito dal metodo iterrows() è una copia, non una vista, quindi modificarlo non aggiornerà i dati originali.
for index, row in df.iterrows():
row['point'] += row['age']
print(df)
# age state point
# Alice 24 NY 64
# Bob 42 CA 92
Puoi aggiornarlo selezionando gli elementi del DataFrame originale con at[].
for index, row in df.iterrows():
df.at[index, 'point'] += row['age']
print(df)
# age state point
# Alice 24 NY 88
# Bob 42 CA 134
Vedere il seguente articolo su at[].
Tuttavia, in molti casi, non è necessario utilizzare un ciclo per aggiornare un elemento o aggiungere nuova colonna basata su una colonna esistente. È più semplice e veloce senza scrivere un ciclo per.
Stesso processo senza un ciclo per:
df = pd.DataFrame({'age': [24, 42], 'state': ['NY', 'CA'], 'point': [64, 92]},
index=['Alice', 'Bob'])
df['point'] += df['age']
print(df)
# age state point
# Alice 24 NY 88
# Bob 42 CA 134
Puoi aggiungere una nuova colonna.
df['new'] = df['point'] + df['age'] * 2
print(df)
# age state point new
# Alice 24 NY 88 136
# Bob 42 CA 134 218
Puoi anche applicare le funzioni NumPy a ciascun elemento di una colonna.
df['age_sqrt'] = np.sqrt(df['age'])
print(df)
# age state point new age_sqrt
# Alice 24 NY 88 136 4.898979
# Bob 42 CA 134 218 6.480741
Per le stringhe, vengono forniti vari metodi per elaborare direttamente le colonne. Quello che segue è un esempio di conversione in minuscolo e selezione del primo carattere.
df['state_0'] = df['state'].str.lower().str[0]
print(df)
# age state point new age_sqrt state_0
# Alice 24 NY 88 136 4.898979 n
# Bob 42 CA 134 218 6.480741 c
Confronto di velocità
Confronta la velocità di iterrows(), itertuple() e il metodo per specificare le colonne.
Usa pandas.DataFrame con 100 righe e 10 colonne come esempio. È un semplice esempio con solo elementi numerici, l’indice del nome della riga e le colonne del nome della colonna sono numeri sequenziali predefiniti.
import pandas as pd
df = pd.DataFrame(pd.np.arange(1000).reshape(100, 10))
print(df.shape)
# (100, 10)
print(df.head())
# 0 1 2 3 4 5 6 7 8 9
# 0 0 1 2 3 4 5 6 7 8 9
# 1 10 11 12 13 14 15 16 17 18 19
# 2 20 21 22 23 24 25 26 27 28 29
# 3 30 31 32 33 34 35 36 37 38 39
# 4 40 41 42 43 44 45 46 47 48 49
print(df.tail())
# 0 1 2 3 4 5 6 7 8 9
# 95 950 951 952 953 954 955 956 957 958 959
# 96 960 961 962 963 964 965 966 967 968 969
# 97 970 971 972 973 974 975 976 977 978 979
# 98 980 981 982 983 984 985 986 987 988 989
# 99 990 991 992 993 994 995 996 997 998 999
Si noti che il codice seguente utilizza il comando magico di Jupyter Notebook %%timeit e non funziona se come script Python.
%%timeit
for i, row in df.iterrows():
pass
# 4.53 ms ± 325 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%%timeit
for t in df.itertuples():
pass
# 981 µs ± 43.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%%timeit
for t in df.itertuples(name=None):
pass
# 718 µs ± 10.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%%timeit
for i in df[0]:
pass
# 15.6 µs ± 446 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%%timeit
for i, j, k in zip(df[0], df[4], df[9]):
pass
# 46.1 µs ± 588 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%%timeit
for t in zip(df[0], df[1], df[2], df[3], df[4], df[5], df[6], df[7], df[8], df[9]):
pass
# 147 µs ± 3.78 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
iterrows() è lento perché converte ogni riga in pandas.Series.
itertuple() è più veloce di iterrows(), ma il metodo per specificare le colonne è il più veloce. Nell’ambiente di esempio, è più veloce di itertuple() anche se sono specificate tutte le colonne.
All’aumentare del numero di righe, iterrows() diventa ancora più lento. Dovresti provare a usare itertuples() o la specifica della colonna in questo caso.
Naturalmente, come accennato in precedenza, è meglio non utilizzare il ciclo per se non è necessario.