HOWTO · Pandas

Contare i valori unici per gruppo in Pandas

contare i valori raggruppando le colonne in DataFrame utilizzando i metodi df.groupby(). nunique(), df.groupby(). agg() e df.groupby(). unique() nella libreria pandas

In questa pagina

Quando analizzi un DataFrame, spesso devi sapere quanti valori distinti compaiono all’interno di ciascun gruppo anziché nell’intera colonna. Ad esempio, un set di dati potrebbe registrare quali valori di code usa ciascuna voce in Countries, e tu vuoi un conteggio per paese. L’operazione groupby() di pandas offre tre strumenti pratici per questo compito:

  1. df.groupby().nunique() restituisce il numero di valori distinti in ciascun gruppo.
  2. df.groupby().agg() applica lo stesso conteggio attraverso l’interfaccia di aggregazione generale.
  3. df.groupby().unique() elenca i valori distinti stessi per ciascun gruppo.

Tutti gli esempi seguenti usano lo stesso DataFrame, costruito da nove righe di coppie paese-codice.

Esegui questo esempio:

Il codice e le etichette o gli output visibili in questa sezione restano in inglese.

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

Contare i valori unici con GroupBy.nunique()

Il modo più diretto per contare i valori distinti per gruppo è nunique(). Selezionando la colonna code dopo groupby(), l’oggetto raggruppato diventa una Series raggruppata, quindi nunique() conta i diversi codici all’interno delle righe di ciascun paese.

Il codice e le etichette o gli output visibili in questa sezione restano in inglese.

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

Il risultato è una Series il cui indice contiene i nomi dei gruppi e i cui valori contengono i conteggi: la Svizzera usa tre codici distinti, la Germania e il Giappone ne usano due ciascuno e il Canada ne usa uno. Poiché le chiavi di gruppo sono diventate l’indice, chiama reset_index() se vuoi un DataFrame piatto a due colonne, oppure usa la forma agg() della sezione successiva. Per impostazione predefinita nunique() non conta le voci mancanti (NaN); passa dropna=False se i valori mancanti devono contare come un valore distinto.

Contare i valori unici con GroupBy.agg()

agg() è il metodo di aggregazione generale di un oggetto raggruppato. Passando nunique() come funzione di aggregazione si ottengono gli stessi conteggi attraverso l’interfaccia DataFrame.aggregate(), con un maggiore controllo sulla forma del risultato.

Il codice e le etichette o gli output visibili in questa sezione restano in inglese.

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

Il dizionario {"code": pd.Series.nunique} indica a agg() quale colonna aggregare e quale funzione applicare; pd.Series.nunique è la stessa operazione chiamata direttamente nella sezione precedente, e passare il suo nome come stringa — agg({"code": "nunique"}) — funziona in modo identico. L’argomento as_index=False mantiene i nomi dei paesi come colonna normale invece di spostarli nell’indice, ed è per questo che result è un DataFrame piatto anziché una Series indicizzata. Scegli questa forma quando vuoi un risultato DataFrame o quando il conteggio dei distinti è una delle varie aggregazioni calcolate in un unico passaggio.

Elencare i valori unici con GroupBy["code"].unique()

Un conteggio risponde alla domanda «quanti», ma a volte devi sapere quali codici usa ciascun paese. Applicando unique() a una Series raggruppata si ottengono i valori distinti stessi.

Il codice e le etichette o gli output visibili in questa sezione restano in inglese.

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

Ogni voce del risultato è un array dei valori distinti di code osservati per quel paese, in ordine di apparizione — l’array della Svizzera conferma i tre codici contati in precedenza: 999, 113 e 112. Poiché ogni elemento è un array anziché un singolo numero, la Series ha dtype object. Una differenza di comportamento degna di nota: unique() include un NaN nell’array restituito, mentre nunique() salta i valori mancanti per impostazione predefinita.

Scegliere tra conteggio ed elenco dei valori

Scegli nunique() quando la domanda è quantitativa — «quanti codici distinti usa ciascun paese?». Restituisce conteggi numerici ordinati che puoi ordinare, filtrare o ricongiungere alle righe originali. Per aggiungere il conteggio del gruppo di ogni riga come nuova colonna, usa df.groupby("Countries")["code"].transform("nunique"), che propaga il conteggio per gruppo a ogni riga.

Scegli unique() quando conta l’identità dei valori — ad esempio, per verificare quali codici sono condivisi tra i paesi o per passare gli elenchi di valori a un passaggio di elaborazione successivo. Se hai già il risultato di unique() e ti servono le sue lunghezze, result.apply(len) riproduce gli stessi conteggi che darebbe nunique().

Infine, usa agg() quando un conteggio dei distinti è solo una parte di un’aggregazione più ampia, come agg({"code": "nunique", "price": "sum"}), che calcola diverse statistiche per gruppo in un unico passaggio. In breve: nunique() per il conteggio, unique() per i valori e agg() quando ti serve un risultato DataFrame o vuoi combinare il conteggio con altre aggregazioni.