Skip to content

pandas : Iterate DataFrame avec la boucle « for

Si pandas.DataFrame est itéré par la boucle for telle quelle, les noms de colonne sont renvoyés. Vous pouvez parcourir les colonnes et les lignes de pandas.DataFrame avec les méthodes iteritems(), iterrows() et itertuples().

Cet article décrit le contenu suivant.

  • Itérer pandas.DataFrame dans la boucle for telle quelle
  • Itérer les colonnes de pandas.DataFrame
  • Itérer les lignes de pandas.DataFrame
    • DataFrame.iterrows()
    • DataFrame.itertuples()
  • Itérer uniquement des colonnes spécifiques
  • Mettre à jour les valeurs dans la boucle for
  • Comparaison de vitesse

Pour plus d’informations sur l’instruction for en Python, consultez l’article suivant.

Utilisez le pandas.DataFrame suivant comme exemple.

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

Itérer pandas.DataFrame dans la boucle for telle quelle

Si vous itérez pandas.DataFrame dans une boucle for tel quel, les noms de colonnes sont renvoyés dans l’ordre.

for column_name in df:
    print(column_name)
# age
# state
# point

Itérer les colonnes de pandas.DataFrame

DataFrame.iteritems()

La méthode iteritems() itère sur les colonnes et renvoie (nom de la colonne, Series), un tuple avec le nom de la colonne et le contenu en tant que 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
# ======
# 

Itérer les lignes de pandas.DataFrame

Les méthodes iterrows() et itertuples() itèrent sur les lignes. La méthode itertuples() est plus rapide.

Si vous n’avez besoin que des valeurs d’une colonne particulière, il est encore plus rapide de parcourir les éléments d’une colonne donnée individuellement, comme expliqué ci-après. Les résultats de la comparaison de vitesse sont affichés à la fin.

DataFrame.iterrows()

La méthode iterrows() itère sur les lignes et renvoie (index, Series), un tuple avec l’index et le contenu comme 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()

La méthode itertuples() itère sur les lignes et renvoie un tuple de l’index et du contenu. Le premier élément du tuple est l’index.

Par défaut, il renvoie un tuple nommé nommé Pandas. Comme il s’agit d’un tuple nommé, vous pouvez accéder à la valeur de chaque élément par . aussi bien que [].

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
# ======
# 

Un tuple normal est renvoyé si le paramètre name est défini sur 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
# ======
# 

Itérer uniquement des colonnes spécifiques

Si vous n’avez besoin que des éléments d’une colonne particulière, vous pouvez également écrire comme suit.

La colonne pandas.DataFrame est pandas.Series.

print(df['age'])
# Alice    24
# Bob      42
# Name: age, dtype: int64

print(type(df['age']))
# <class 'pandas.core.series.Series'>

Si vous appliquez pandas.Series à une boucle for, vous pouvez obtenir ses valeurs dans l’ordre. Vous pouvez obtenir les valeurs de cette colonne dans l’ordre en spécifiant une colonne de pandas.DataFrame et en l’appliquant à une boucle for.

for age in df['age']:
    print(age)
# 24
# 42

Vous pouvez également obtenir les valeurs de plusieurs colonnes avec la fonction intégrée zip().

for age, point in zip(df['age'], df['point']):
    print(age, point)
# 24 64
# 42 92

Utilisez l’attribut index si vous souhaitez obtenir l’index. Comme dans l’exemple ci-dessus, vous pouvez le réunir avec d’autres colonnes par 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

Mettre à jour les valeurs dans la boucle for

Le pandas.Series retourné par la méthode iterrows() est une copie, pas une vue, donc le changer ne mettra pas à jour les données d’origine.

for index, row in df.iterrows():
    row['point'] += row['age']

print(df)
#        age state  point
# Alice   24    NY     64
# Bob     42    CA     92

Vous pouvez le mettre à jour en sélectionnant des éléments du DataFrame d’origine avec 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

Voir l’article suivant sur [].

Cependant, dans de nombreux cas, il n’est pas nécessaire d’utiliser une boucle for pour mettre à jour un élément ou pour ajouter une nouvelle colonne basée sur une colonne existante. Il est plus simple et plus rapide d’écrire sans boucle for.

Même processus sans boucle for :

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

Vous pouvez ajouter une nouvelle colonne.

df['new'] = df['point'] + df['age'] * 2
print(df)
#        age state  point  new
# Alice   24    NY     88  136
# Bob     42    CA    134  218

Vous pouvez également appliquer des fonctions NumPy à chaque élément d’une colonne.

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

Pour les chaînes, diverses méthodes sont fournies pour traiter directement les colonnes. Voici un exemple de conversion en minuscules et de sélection du premier caractère.

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

Comparaison de vitesse

Comparez la vitesse de iterrows(), itertuples() et la méthode de spécification des colonnes.

Utilisez pandas.DataFrame avec 100 lignes et 10 colonnes comme exemple. Il s’agit d’un exemple simple avec uniquement des éléments numériques, l’index de nom de ligne et les colonnes de nom de colonne sont des numéros séquentiels par défaut.

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

Notez que le code ci-dessous utilise la commande magique Jupyter Notebook %%timeit et ne fonctionne pas lorsqu’il est exécuté en tant que 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() est lent car il convertit chaque ligne en pandas.Series.

itertuples() est plus rapide que iterrows(), mais la méthode de spécification des colonnes est la plus rapide. Dans l’exemple d’environnement, il est plus rapide que itertuples() même si toutes les colonnes sont spécifiées.

À mesure que le nombre de lignes augmente, iterrows() devient encore plus lent. Vous devriez essayer d’utiliser itertuples() ou la spécification de colonne dans un tel cas.

Bien sûr, comme mentionné ci-dessus, il est préférable de ne pas utiliser la boucle for si ce n’est pas nécessaire.