Menu
CoddyTech

Pandas Cheat Sheet

Ultimo aggiornamento

Creare un DataFrame

Piccoli DataFrame costruiti a mano, per esempi, test e tabelle di riferimento.

AttivitàCodice
Importare pandas e NumPyimport pandas as pd import numpy as np
Da un dict di colonnedf = pd.DataFrame({"name": ["Ada", "Ben"], "age": [36, 28]})
Da una lista di righepd.DataFrame([{"name": "Ada", "age": 36}, {"name": "Ben", "age": 28}])
Da un array NumPypd.DataFrame(np.arange(6).reshape(3, 2), columns=["x", "y"])
Una Series con etichettes = pd.Series([3, 5, 2], index=["a", "b", "c"])
Un intervallo di datepd.date_range("2026-01-01", periods=7, freq="D")

Leggere e scrivere file

Una chiamata carica un file in un DataFrame, un'altra lo riscrive su disco.

AttivitàCodice
Leggere un file CSVdf = pd.read_csv("sales.csv")
Solo alcune colonne, con date verepd.read_csv("sales.csv", usecols=["date", "city", "sales"], parse_dates=["date"])
Usare una colonna come indicepd.read_csv("sales.csv", index_col="id")
Tab o altro separatorepd.read_csv("sales.tsv", sep="\t")
Altri marcatori come valori mancantipd.read_csv("sales.csv", na_values=["n/a", "-"])
Leggere solo le prime righepd.read_csv("sales.csv", nrows=1000)
Leggere un foglio Excel (serve openpyxl)pd.read_excel("report.xlsx", sheet_name="2026")
Leggere record JSONpd.read_json("records.json")
Leggere da un database SQLpd.read_sql("SELECT * FROM orders", conn)
Scrivere un CSV senza indicedf.to_csv("clean.csv", index=False)
Scrivere Excel o Parquetdf.to_excel("clean.xlsx", index=False), df.to_parquet("clean.parquet")

Esplorare i dati

Le prime chiamate da fare su qualsiasi nuovo dataset.

AttivitàCodice
Prime e ultime righedf.head(), df.tail(3)
Numero di righe e colonnedf.shape # (6, 7)
Tipi delle colonne e valori non nullidf.info()
Statistiche delle colonne numerichedf.describe()
Riepilogo di tutte le colonnedf.describe(include="all")
Nomi e tipi delle colonnedf.columns, df.dtypes
Contare ogni valoredf["city"].value_counts()
Percentuale di ogni valoredf["city"].value_counts(normalize=True)
Valori distinti e quanti sonodf["city"].unique(), df["city"].nunique()
Valori mancanti per colonnadf.isna().sum()
Campione casuale di righedf.sample(3, random_state=0)
Correlazione tra colonne numerichedf.corr(numeric_only=True)

Selezionare colonne e righe

loc seleziona per etichetta e include la fine di uno slice. iloc seleziona per posizione e la esclude.

AttivitàCodice
Una colonna, come Seriesdf["age"]
Più colonne, come DataFramedf[["name", "age"]]
Righe e colonne per etichettadf.loc[0:2, ["name", "age"]]
Righe e colonne per posizionedf.iloc[0:2, 0:3]
Un singolo valoredf.at[0, "age"], df.iat[0, 3]
Ultima rigadf.iloc[-1]
Colonne di un certo tipodf.select_dtypes(include="number")
Colonne di testo (pandas 3)df.select_dtypes(include="str")
Colonne per corrispondenza nel nomedf.filter(like="sal"), df.filter(regex="^(age|salary)$")
Cercare righe tramite una colonnadf.set_index("name").loc["Ada", "salary"]
Tornare a un indice 0, 1, 2df.reset_index(drop=True)
Eliminare colonne o righedf.drop(columns=["email"]), df.drop(index=[0, 1])

Filtrare le righe

Metti ogni condizione tra parentesi e combinale con & (and), | (or) e ~ (not).

AttivitàCodice
Righe che soddisfano una condizionedf[df["age"] > 30]
Entrambe le condizionidf[(df["age"] > 30) & (df["city"] == "Oslo")]
Almeno una condizionedf[(df["city"] == "Oslo") | (df["salary"] > 6000)]
Valore in una listadf[df["city"].isin(["Oslo", "Rome"])]
Valore non in una listadf[~df["city"].isin(["Oslo", "Rome"])]
Tra due valori, estremi inclusidf[df["age"].between(30, 40)]
Filtrare con una query testualedf.query("age > 30 and city == 'Oslo'")
Usare una variabile in una querymin_age = 30 df.query("age > @min_age")
Il testo contienedf[df["name"].str.contains("e", case=False)]
Valori mancanti o presentidf[df["age"].isna()], df[df["age"].notna()]
Filtrare righe e scegliere colonnedf.loc[df["age"] > 30, ["name", "salary"]]
Le prime o ultime n righedf.nlargest(3, "salary"), df.nsmallest(2, "age")
Righe con un valore ripetutodf[df.duplicated(subset=["city"], keep=False)]

Ordinare e classificare

AttivitàCodice
Ordinare per una colonnadf.sort_values("salary")
Prima i più grandidf.sort_values("salary", ascending=False)
Ordinare per più colonnedf.sort_values(["city", "salary"], ascending=[True, False])
Prima i valori mancantidf.sort_values("age", na_position="first")
Ordinare per indicedf.sort_index()
Classifica, 1 è il più altodf["salary"].rank(ascending=False)

Aggiungere e modificare colonne

Le operazioni su intere colonne sono veloci. Usa apply solo quando nessun metodo integrato fa al caso tuo.

AttivitàCodice
Nuova colonna da altre colonnedf["bonus"] = df["salary"] * 0.1
Aggiungere una colonna in una catenadf.assign(bonus=lambda d: d["salary"] * 0.1)
Valore in base a una condizionedf["level"] = np.where(df["age"] >= 40, "senior", "junior")
Valore in base a più condizionidf["band"] = np.select([df["age"] < 30, df["age"] < 45], ["young", "mid"], default="senior")
Cambiare i valori dove vale una condizionedf.loc[df["city"] == "Lima", "salary"] = 4000
Mappare i valori con un dictdf["country"] = df["city"].map({"Oslo": "NO", "Rome": "IT", "Lima": "PE"})
Applicare una funzione a una colonnadf["salary"].apply(lambda x: round(x, -3))
Applicare una funzione a ogni celladf[["age", "salary"]].map(lambda x: x / 1000)
Rinominare le colonnedf.rename(columns={"salary": "pay"})
Cambiare il tipo di una colonnadf["salary"].astype("float64")
Testo in numeri, valori errati a NaNpd.to_numeric(s, errors="coerce")
Numeri in fasce con etichettapd.cut(df["age"], bins=[0, 30, 45, 120], labels=["young", "mid", "senior"])
Numeri in gruppi di pari dimensionepd.qcut(df["salary"], q=4, labels=False)
Ciclare sulle righe (lento, ultima risorsa)for row in df.itertuples(): print(row.name, row.salary)

Valori mancanti e pulizia

I numeri mancanti appaiono come NaN, le date mancanti come NaT. Ognuna di queste chiamate restituisce un nuovo oggetto, quindi assegna il risultato.

AttivitàCodice
Percentuale di mancanti per colonnadf.isna().mean()
Eliminare righe con valori mancantidf.dropna()
Eliminare righe senza una colonna chiavedf.dropna(subset=["age"])
Riempire con un valore per colonnadf.fillna({"age": df["age"].median()})
Riempire dalla riga precedente o successivadf["age"].ffill(), df["age"].bfill()
Riempire i buchi per interpolazionedf["age"].interpolate()
Trasformare marcatori in valori mancantidf.replace(["n/a", "-", ""], np.nan)
Eliminare righe duplicatedf.drop_duplicates()
Tenere l'ultima riga per chiavedf.drop_duplicates(subset=["city"], keep="last")
Sistemare i nomi delle colonnedf.columns = df.columns.str.strip().str.lower().str.replace(" ", "_")
Limitare i valori estremidf["salary"].clip(lower=4000, upper=6000)
Tipo category per testo ripetutodf["city"] = df["city"].astype("category")

Colonne di testo (.str)

In pandas 3 le colonne di testo hanno di default il dtype str. I metodi .str lavorano sull'intera colonna e i valori mancanti restano mancanti.

AttivitàCodice
Maiuscolo, minuscolo o iniziali maiuscoledf["name"].str.upper(), df["name"].str.lower(), df["name"].str.title()
Togliere gli spazidf["name"].str.strip()
Sostituire testodf["email"].str.replace("mail.com", "example.com")
Sostituire con una regexdf["email"].str.replace(r"@.*", "", regex=True)
Contiene, inizia condf["name"].str.contains("a"), df["name"].str.startswith("E")
Lunghezza di ogni valoredf["name"].str.len()
Primi caratteridf["name"].str[:2]
Dividere in colonnedf["email"].str.split("@", expand=True)
Estrarre con un gruppo regexdf["email"].str.extract(r"@(\w+)")
Unire colonne di testodf["name"] + " (" + df["city"] + ")"
Riempire i numeri con zeridf["salary"].astype("str").str.zfill(6)
Il nuovo dtype per il testodf["name"].dtype # str

Date e orari

L'accessor .dt funziona sulle colonne datetime. Un indice di date ordinato (ts qui sotto) permette lo slicing con stringhe e il resampling.

AttivitàCodice
Convertire una colonna in datetimedf["date"] = pd.to_datetime(df["date"])
Convertire con un formato esattopd.to_datetime(["03/01/2026", "15/01/2026"], format="%d/%m/%Y")
Anno, mese, nome del giornodf["date"].dt.year, df["date"].dt.month, df["date"].dt.day_name()
Raggruppare le date per mesedf["date"].dt.to_period("M")
Giorni tra due date(pd.Timestamp("2026-12-31") - df["date"]).dt.days
Aggiungere giorni o mesidf["date"] + pd.Timedelta(days=30), df["date"] + pd.DateOffset(months=1)
Righe in un intervallo di datedf[df["date"].between("2021-01-01", "2022-12-31")]
Indice di date, slicing con stringhets = df.set_index("date").sort_index() ts.loc["2021":"2022"]
Totale per mesets["salary"].resample("ME").sum()
Media settimanale; "QE" è trimestrale, "YE" annualets["salary"].resample("W").mean()
Media mobilets["salary"].rolling(3).mean()
Variazione rispetto alla riga precedentets["salary"].diff(), ts["salary"].pct_change()
Spostare i valori giù di una rigats["salary"].shift(1)
Totale cumulativots["salary"].cumsum()
Impostare e convertire i fusi orarits.index.tz_localize("UTC").tz_convert("Europe/Oslo")

Raggruppare e aggregare

groupby divide le righe per chiave, applica una funzione a ogni gruppo e combina i risultati.

AttivitàCodice
Media per gruppodf.groupby("city")["salary"].mean()
Più statistiche insiemedf.groupby("city")["salary"].agg(["mean", "max", "count"])
Colonne risultato con nomedf.groupby("city").agg(avg_pay=("salary", "mean"), people=("name", "count"))
Raggruppare per due colonnedf.groupby(["city", "team"])["salary"].sum()
Tenere le chiavi come colonnedf.groupby("city", as_index=False)["salary"].mean()
Numero di righe per gruppodf.groupby("city").size()
Risultato del gruppo su ogni rigadf["city_avg"] = df.groupby("city")["salary"].transform("mean")
Tenere solo alcuni gruppidf.groupby("city").filter(lambda g: len(g) >= 2)
Riga con il massimo per gruppodf.loc[df.groupby("city")["salary"].idxmax()]
Prime n righe per gruppodf.sort_values("salary", ascending=False).groupby("city").head(2)
Numerare le righe di ogni gruppodf.groupby("city").cumcount()
Ciclare sui gruppifor city, group in df.groupby("city"): print(city, len(group))
Filtrare, raggruppare e ordinare in una catena(df.query("age > 30") .groupby("city", as_index=False) .agg(avg_pay=("salary", "mean")) .sort_values("avg_pay", ascending=False))

Pivot e rimodellamento

I dati in formato lungo hanno una riga per osservazione. Quelli in formato largo distribuiscono una variabile su più colonne.

AttivitàCodice
Tabella pivotdf.pivot_table(index="city", columns="team", values="salary", aggfunc="mean", fill_value=0)
Tabella pivot con totalidf.pivot_table(index="city", values="salary", aggfunc="sum", margins=True)
Contare le combinazionipd.crosstab(df["city"], df["team"])
Percentuali per rigapd.crosstab(df["city"], df["team"], normalize="index")
Da largo a lungolong = df.melt(id_vars="name", value_vars=["age", "salary"], var_name="field", value_name="value")
Da lungo a largolong.pivot(index="name", columns="field", values="value")
Livello interno dell'indice in colonnedf.groupby(["city", "team"])["salary"].sum().unstack(fill_value=0)
Una riga per elemento della listapd.DataFrame({"id": [1, 2], "tags": [["a", "b"], ["c"]]}).explode("tags")
One-hot encoding di una colonnapd.get_dummies(df["team"], prefix="team")
Scambiare righe e colonnedf.T

Combinare DataFrame

concat impila i frame, merge li unisce su colonne chiave come una join SQL.

AttivitàCodice
Impilare righepd.concat([df_2025, df_2026], ignore_index=True)
Affiancarepd.concat([left, right], axis=1)
Join su una colonna chiaveorders.merge(customers, on="customer_id", how="left")
Tipi di joinhow="inner", "left", "right", "outer"
Chiavi con nomi diversiorders.merge(users, left_on="customer_id", right_on="id")
Verificare la join e segnare la provenienzaorders.merge(customers, on="customer_id", how="left", validate="many_to_one", indicator=True)
Join sull'indiceleft.join(right, how="inner")
Righe senza corrispondenza in un'altra tabellaorders[~orders["customer_id"].isin(customers["customer_id"])]

Grafici con pandas

pandas disegna con Matplotlib. Ogni chiamata di plot restituisce un ax di Matplotlib, così puoi continuare a personalizzarlo.

AttivitàCodice
Grafico a linee di una seriets["salary"].plot()
Grafico a linee da due colonnedf.plot(x="date", y="salary")
Grafico a barre di un riepilogodf.groupby("city")["salary"].mean().plot.bar()
Barre orizzontali ordinatedf["city"].value_counts().sort_values().plot.barh()
Istogrammadf["salary"].plot.hist(bins=20)
Grafico a dispersionedf.plot.scatter(x="age", y="salary")
Box plot per gruppodf.boxplot(column="salary", by="city")
Titolo ed etichetta dell'asseax = df.plot(x="date", y="salary", title="Salary") ax.set_ylabel("EUR")
Mostrare o salvare il graficoplt.show(), ax.figure.savefig("salary.png", dpi=150)

pandas 3: vecchie forme e cosa scrivere ora

Il codice copiato da tutorial più vecchi spesso dà errore o avvisi in pandas 3. Usa invece le forme della colonna pandas 3.

Attivitàpandas 3Vecchia forma
Funzione su ogni celladf.map(f)df.applymap(f)
Riempire dalla riga precedentedf.ffill()df.fillna(method="ffill")
Aggiungere righepd.concat([df, new_rows])df.append(new_rows)
Resampling a fine mesets["salary"].resample("ME").sum()resample("M")
Date orariepd.date_range("2026-01-01", periods=24, freq="h")freq="H"
Impostare un singolo valoredf.loc[0, "age"] = 37df["age"][0] = 37
Modificare un sottoinsieme filtratohigh = df[df["salary"] > 5000] high["salary"] = 0high = df[df["salary"] > 5000].copy()
È una colonna di testo?df["name"].dtype == "str"df["name"].dtype == object

Il codice pandas che un data analyst usa tutti i giorni, raggruppato per attività: creare e caricare dati, esplorarli, selezionare e filtrare righe, aggiungere colonne, gestire i valori mancanti, lavorare con testo e date, raggruppare e aggregare, rimodellare, unire e creare grafici. Ogni riga è un breve snippet da incollare, con una riga che spiega cosa fa.

Tutto è scritto per pandas 3, la versione che usa Coddy: le colonne di testo hanno il nuovo dtype str, il Copy-on-Write è sempre attivo e le API rimosse come applymap e fillna(method=...) compaiono solo nella tabella delle vecchie forme. Gli esempi usano un DataFrame df con le colonne name, city, team, age, salary, date e email. Sei alle prime armi con Python? Parti dal Python cheat sheet e dal playground Python, e tieni a portata di mano anche i cheat sheet di NumPy, Matplotlib e scikit-learn.

FAQ sul cheat sheet di pandas

Questo cheat sheet di pandas è gratuito?
Sì. Questo cheat sheet di pandas è completamente gratuito e non serve registrarsi. Salvalo nei preferiti o stampalo in PDF dal browser, e tornaci ogni volta che ti serve la chiamata esatta per un groupby, un merge o una tabella pivot.
Quale versione di pandas copre questo cheat sheet?
pandas 3. Le colonne di testo usano il nuovo dtype str, il Copy-on-Write è sempre attivo e le chiamate rimosse in pandas 3 (applymap, fillna(method=...), append, gli alias di frequenza M e H) compaiono solo nell'ultima tabella, accanto a cosa scrivere al loro posto. Quasi tutti gli snippet funzionano anche su pandas 2.2, tranne le righe che si basano sul dtype str o sul Copy-on-Write.
Qual è la differenza tra loc e iloc?
loc seleziona per etichetta, cioè i valori dell'indice e i nomi delle colonne, e uno slice come df.loc[0:2] include la fine. iloc seleziona per posizione intera, come una lista Python, quindi df.iloc[0:2] restituisce le prime due righe ed esclude la fine. Usa loc con una condizione per filtrare le righe e scegliere le colonne in un solo passaggio: df.loc[df["age"] > 30, ["name"]].
Come filtro un DataFrame con più condizioni?
Metti ogni condizione tra parentesi e uniscile con & per and, | per or e ~ per not: df[(df["age"] > 30) & (df["city"] == "Oslo")]. Gli operatori Python and e or non funzionano su intere colonne. Per filtri lunghi, df.query("age > 30 and city == 'Oslo'") è più leggibile.
Qual è la differenza tra merge, join e concat?
merge combina due DataFrame su colonne chiave, come una join SQL, con how="inner", "left", "right" o "outer". join è una scorciatoia che fa il merge sull'indice. concat non confronta nessuna chiave: impila i frame uno sopra l'altro, oppure li affianca con axis=1.
Perché la mia assegnazione non modifica il DataFrame?
Da pandas 3, con il Copy-on-Write ogni selezione si comporta come una copia. Un'assegnazione concatenata come df["age"][0] = 37 modifica un oggetto temporaneo e lascia df invariato. Scrivila invece come un'unica chiamata loc: df.loc[0, "age"] = 37. Anche metodi come dropna e fillna restituiscono un nuovo oggetto, quindi assegna il risultato.
Posso eseguire codice pandas online?
Sì. Il playground Matplotlib gratuito esegue Python con pandas, NumPy, Matplotlib e scikit-learn nel browser, così puoi incollare qualsiasi snippet di questo cheat sheet ed eseguirlo senza installare nulla. Il corso di Machine Learning di Coddy insegna pandas passo dopo passo, dal tuo primo DataFrame fino ai dati che alimentano un modello.
Illustrazione dei linguaggi di programmazione di Coddy

Impara Pandas con Coddy

INIZIA