HOWTO · Pandas

Compter des valeurs uniques par groupe(s) dans Pandas

compter les valeurs en regroupant la colonne dans DataFrame à l'aide des méthodes df.groupby(). nunique(), df.groupby(). agg() et df.groupby(). unique() dans la bibliothèque pandas

Sur cette page

Lorsque vous analysez un DataFrame, vous devez souvent savoir combien de valeurs distinctes apparaissent dans chaque groupe, plutôt que dans l’ensemble de la colonne. Par exemple, un jeu de données peut enregistrer quelles valeurs de code chaque entrée de Countries utilise, et vous souhaitez obtenir un décompte par pays. L’opération pandas groupby() propose trois outils pratiques pour cette tâche :

  1. df.groupby().nunique() renvoie le nombre de valeurs distinctes dans chaque groupe.
  2. df.groupby().agg() applique le même décompte via l’interface d’agrégation générale.
  3. df.groupby().unique() liste les valeurs distinctes elles-mêmes pour chaque groupe.

Tous les exemples ci-dessous utilisent le même DataFrame, construit à partir de neuf lignes de paires pays-code.

Exécutez cet exemple :

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

import pandas as pd

data = [
    [999, "Switzerland"],
    [113, "Switzerland"],
    [112, "Japan"],
    [112, "Switzerland"],
    [113, "Canada"],
    [114, "Japan"],
    [100, "Germany"],
    [114, "Japan"],
    [115, "Germany"],
]
df = pd.DataFrame(data, columns=["code", "Countries"])
print(df)
   code    Countries
0   999  Switzerland
1   113  Switzerland
2   112        Japan
3   112  Switzerland
4   113       Canada
5   114        Japan
6   100      Germany
7   114        Japan
8   115      Germany

Compter les valeurs uniques avec GroupBy.nunique()

La façon la plus directe de compter les valeurs distinctes par groupe est nunique(). La sélection de la colonne code après groupby() transforme l’objet groupé en une Series groupée, de sorte que nunique() compte les différents codes dans les lignes de chaque pays.

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

import pandas as pd

data = [
    [999, "Switzerland"],
    [113, "Switzerland"],
    [112, "Japan"],
    [112, "Switzerland"],
    [113, "Canada"],
    [114, "Japan"],
    [100, "Germany"],
    [114, "Japan"],
    [115, "Germany"],
]
df = pd.DataFrame(data, columns=["code", "Countries"])
result = df.groupby("Countries")["code"].nunique()
print(result)
Countries
Canada         1
Germany        2
Japan          2
Switzerland    3
Name: code, dtype: int64

Le résultat est une Series dont l’index contient les noms des groupes et dont les valeurs contiennent les décomptes : la Suisse utilise trois codes distincts, l’Allemagne et le Japon en utilisent deux chacun, et le Canada un seul. Comme les clés de groupe sont devenues l’index, appelez reset_index() si vous voulez un DataFrame plat à deux colonnes, ou utilisez la forme agg() de la section suivante. Par défaut, nunique() ne compte pas les entrées manquantes (NaN) ; passez dropna=False si les valeurs manquantes doivent compter comme une valeur distincte.

Compter les valeurs uniques avec GroupBy.agg()

agg() est la méthode d’agrégation générale d’un objet groupé. Passer nunique() comme fonction d’agrégation produit les mêmes décomptes via l’interface DataFrame.aggregate(), avec davantage de contrôle sur la forme du résultat.

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

import pandas as pd

data = [
    [999, "Switzerland"],
    [113, "Switzerland"],
    [112, "Japan"],
    [112, "Switzerland"],
    [113, "Canada"],
    [114, "Japan"],
    [100, "Germany"],
    [114, "Japan"],
    [115, "Germany"],
]
df = pd.DataFrame(data, columns=["code", "Countries"])
result = df.groupby(by="Countries", as_index=False).agg({"code": pd.Series.nunique})
print(result)
     Countries  code
0       Canada     1
1      Germany     2
2        Japan     2
3  Switzerland     3

Le dictionnaire {"code": pd.Series.nunique} indique à agg() quelle colonne agréger et quelle fonction appliquer ; pd.Series.nunique est la même opération que celle appelée directement dans la section précédente, et passer son nom sous forme de chaîne — agg({"code": "nunique"}) — fonctionne de manière identique. L’argument as_index=False conserve les noms de pays dans une colonne ordinaire au lieu de les déplacer dans l’index, c’est pourquoi result est un DataFrame plat plutôt qu’une Series indexée. Choisissez cette forme lorsque vous voulez un résultat DataFrame ou lorsque le décompte distinct n’est qu’une agrégation parmi plusieurs calculées en une seule passe.

Lister les valeurs uniques avec GroupBy["code"].unique()

Un décompte répond à la question « combien », mais vous devez parfois savoir quels codes chaque pays utilise. Appliquer unique() à une Series groupée renvoie les valeurs distinctes elles-mêmes.

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

import pandas as pd

data = [
    [999, "Switzerland"],
    [113, "Switzerland"],
    [112, "Japan"],
    [112, "Switzerland"],
    [113, "Canada"],
    [114, "Japan"],
    [100, "Germany"],
    [114, "Japan"],
    [115, "Germany"],
]
df = pd.DataFrame(data, columns=["code", "Countries"])
result = df.groupby("Countries")["code"].unique()
print(result)
Countries
Canada                   [113]
Germany             [100, 115]
Japan               [112, 114]
Switzerland    [999, 113, 112]
Name: code, dtype: object

Chaque entrée du résultat est un tableau des valeurs code distinctes observées pour ce pays, dans leur ordre d’apparition — le tableau de la Suisse confirme les trois codes comptés précédemment : 999, 113 et 112. Comme chaque élément est un tableau plutôt qu’un nombre unique, la Series a le dtype object. Une différence de comportement mérite d’être notée : unique() inclut un NaN dans le tableau renvoyé, tandis que nunique() ignore les valeurs manquantes par défaut.

Choisir entre compter et lister les valeurs

Choisissez nunique() lorsque la question est quantitative — « combien de codes distincts chaque pays utilise-t-il ? ». Elle renvoie des décomptes numériques propres que vous pouvez trier, filtrer ou joindre aux lignes d’origine. Pour attacher le décompte du groupe de chaque ligne comme nouvelle colonne, utilisez df.groupby("Countries")["code"].transform("nunique"), qui diffuse le décompte par groupe à chaque ligne.

Choisissez unique() lorsque l’identité des valeurs compte — par exemple, pour vérifier quels codes sont partagés entre les pays ou pour transmettre les listes de valeurs à une étape de traitement ultérieure. Si vous détenez déjà le résultat de unique() et avez besoin de ses longueurs, result.apply(len) reproduit les mêmes décomptes que ceux que nunique() donnerait.

Enfin, utilisez agg() lorsque le décompte distinct n’est qu’une partie d’une agrégation plus large, comme agg({"code": "nunique", "price": "sum"}), qui calcule plusieurs statistiques par groupe en une seule passe. En résumé : nunique() pour le décompte, unique() pour les valeurs, et agg() lorsque vous avez besoin d’un résultat DataFrame ou que vous voulez combiner le décompte avec d’autres agrégations.