DBNomics Eurostat¶

  • https://opendata.marche.camcom.it/eurostat.htm

piattaforma open-source e open-data che raccoglie e rende disponibili gratuitamente dati economici provenienti da decine di fonti ufficiali, tra cui Eurostat (statistica dell’UE)

L’obiettivo è offrire un punto di accesso unificato ai dati economici, con API standardizzate e strumenti per analisi automatizzate.

I dati sono suddivisi in grandi temi statistici, tra cui:

  • Economia e finanza
  • Condizioni sociali e demografia
  • Energia e ambiente
  • Agricoltura
  • Trasporti
  • Innovazione e tecnologia

Ogni dataset include anche metadati (unità di misura, frequenza, copertura geografica, ecc.).

DBnomics mette a disposizione diversi strumenti per sviluppatori e analisti:

  • API REST per accedere ai dati via HTTP
  • Client Python (dbnomics): GitHub Python Client
  • Client Stata: utile per analisi econometriche e panel data (vedi guida)
In [1]:
import pandas as pd
from dbnomics import fetch_series, fetch_series_by_api_link
import altair as alt
alt.renderers.enable('default')
from altair import Chart, Scale, Y

PIL|GDP¶

annuale NAMA_10_GDP¶

  • https://db.nomics.world/Eurostat/NAMA_10_GDP?dimensions=%7B%22geo%22%3A%5B%22IT%22%5D%2C%22freq%22%3A%5B%22A%22%5D%2C%22unit%22%3A%5B%22CP_MEUR%22%5D%2C%22na_item%22%3A%5B%22B1GQ%22%5D%7D&tab=list
  • https://api.db.nomics.world/v22/series/Eurostat/NAMA_10_GDP/A.CP_MEUR.B1GQ.IT?format=csv&observations=1

Usa nama_10r_2gdp se stai analizzando aree geografiche ampie, es.:

  • confronto Centro-Nord vs Mezzogiorno
  • analisi su 20 regioni italiane (NUTS 2) o confronti tra Stati europei

Usa nama_10r_3gdp se ti servono dati a livello provinciale o metropolitano, es.:

  • Torino, Milano, Palermo, ecc.
  • politiche locali, ZES, fondi di coesione a livello sub-regionale

nama¶

  • nama_10_gdp: PIL nazionale
  • nama_10r_2gdp: PIL regionale (NUTS2)
  • nama_10r_3gdp: PIL provinciale (NUTS3)
  • nama_10r_2hhinc: Reddito disponibile per regione

namq¶

  • namq_10_gdp: PIL trimestrale per componenti
  • namq_10_a10: Valore aggiunto per attività economica trimestrale
  • namq_10_nf_tr: Reddito e trasferimenti trimestrali
In [3]:
#PIL

NAMA = [
{'dataset':'Eurostat/nama_10r_3gdp/A.EUR.ITC11' , 'label': 'PIL pro capite annuale per la regione ITC11 (Torino)'},
{'dataset':'Eurostat/nama_10r_3gdp/A.EUR_HAB.ITC11' , 'label': 'PIL totale a prezzi costanti 2010 per la regione ITC11 (Torino)'},
{'dataset':'Eurostat/nama_10r_3gdp/A.CLV10_EUR.ITC11' , 'label': 'PIL pro capite a prezzi costanti 2010 per la regione ITC11 (Torino)'},
{'dataset':'Eurostat/nama_10r_3gdp/A.CLV10_EUR_HAB.ITC11' , 'label': ''},
]
    
# Annuale
# Prezzi correnti, milioni di euro
# Prodotto interno lordo ai prezzi di mercato – Italia
NAMA_10_GDP = [
{'dataset':'Eurostat/NAMA_10_GDP/A.CP_MEUR.B1G.IT' , 'label': 'Valore aggiunto lordo'}, # B1G  = valore aggiunto lordo
{'dataset':'Eurostat/NAMA_10_GDP/A.CP_MEUR.B1GQ.IT', 'label': 'PIL'}, # B1GQ = PIL a prezzi di mercato
{'dataset':'Eurostat/NAMA_10_GDP/A.CP_MEUR.P6.IT'  , 'label': 'export'}, # P6 export di beni e servizi P61 Export di beni P62 export di servizi
{'dataset':'Eurostat/NAMA_10_GDP/A.CP_MEUR.P7.IT'  , 'label': 'import'}, # P7 import di beni e servizi P71 import di beni P72 import di servizi
]

# Annuale
# Prezzi correnti, milioni di euro
# Valore aggiunto lordo – Italia
NAMA_10_A10 = [
{'dataset':'Eurostat/NAMA_10_A10/A.CP_MEUR.C.B1G.IT' , 'label': 'Manifattura'},]

# Prodotto interno lordo (PIL) 
# ai prezzi di mercato correnti 
#per regione NUTS 3
NAMA_10R_3GDP = [
{'dataset':'Eurostat/NAMA_10R_3GDP/A.EUR_HAB.ITF46', 'label':"Annuale – Euro per abitante – Foggia"},
{'dataset':'Eurostat/NAMA_10R_3GDP/A.MIO_EUR.ITF', 'label':"Annuale – Milioni di euro – Sud"},]



# Trimestrale
# Prezzi correnti, milioni di euro – Dati corretti per gli effetti di calendario, non destagionalizzati 
# Valore aggiunto lordo – Italia
NAMQ_10_GDP = [
{'dataset':'Eurostat/NAMQ_10_GDP/Q.CP_MEUR.CA.B1G.IT' , 'label': 'Valore aggiunto lordo'},]   
# Trimestrale
# Prezzi correnti, milioni di euro – Dati corretti per gli effetti di calendario, non destagionalizzati 
#Valore aggiunto lordo – Italia
NAMQ_10_A10 = [
{'dataset':'Eurostat/NAMQ_10_A10/Q.CP_MEUR.CA.A.B1G.IT', 'label':"Agricoltura, silvicoltura e pesca"},
{'dataset':'Eurostat/NAMQ_10_A10/Q.CP_MEUR.CA.B-E.B1G.IT', 'label':"Industria (escluse le costruzioni)"},
{'dataset':'Eurostat/NAMQ_10_A10/Q.CP_MEUR.CA.C.B1G.IT', 'label':"Manifattura"},
{'dataset':'Eurostat/NAMQ_10_A10/Q.CP_MEUR.CA.F.B1G.IT', 'label':"Costruzioni"},]
In [4]:
df1 = fetch_series('Eurostat/NAMA_10_A10/A.CLV05_MEUR.C.B1G.IT')
In [5]:
df1 = fetch_series('Eurostat/NAMA_10_GDP/A.CP_MEUR.B1G.IT') # 
df1[['period', 'value']].tail()
Out[5]:
period value
25 2020-01-01 1496321.9
26 2021-01-01 1644016.4
27 2022-01-01 1793606.6
28 2023-01-01 1913567.0
29 2024-01-01 1958459.6
In [6]:
chart = Chart(df1[df1.value.notna()]).mark_line(
    color='#007A53',strokeWidth=3
).encode(
    x=alt.X('period:T', title=None, axis=alt.Axis(labelFlush=False)),
    y=alt.Y('value:Q', scale=alt.Scale(zero=False), title=None),
    tooltip=['period:T', 'value:Q']
).properties(
    width=800, height=300, title='Prodotto interno lordo' 
).configure_title(
    font='Calibri',fontSize=22,anchor='start',     # allinea a sinistra ('start'), centro ('middle'), destra ('end')
    color='#007a53'
) #.mark_area(    interpolate='step-after',    line=True)
chart
Out[6]:

Trimestrale – Volumi concatenati (2005), milioni di euro – Dati destagionalizzati e corretti per gli effetti di calendario – Prodotto interno lordo a prezzi di mercato – Italia¶

In [7]:
# df1 = fetch_series('Eurostat/NAMQ_10_GDP/Q.CLV05_MEUR.CA.B1G.IT')
df1 = fetch_series('Eurostat/NAMQ_10_GDP/Q.CLV05_MEUR.SCA.B1GQ.IT')
# pd.to_datetime(df1['period'])
df1[['period', 'value']].sample()
Out[7]:
period value
78 2014-07-01 353403.4
In [8]:
# df1['value'].plot()
chart = Chart(df1[df1.value.notna()]).mark_line(
    color='#007A53',strokeWidth=3
).encode(
    x=alt.X('period:T', title=None, axis=alt.Axis(labelFlush=False)),
    y=alt.Y('value:Q', scale=alt.Scale(zero=False), title=None),
    tooltip=['period:T', 'value:Q']
).properties(
    width=900, height=300, title='Prodotto interno lordo' 
).configure_title(
    font='Calibri',fontSize=22,anchor='start',     # allinea a sinistra ('start'), centro ('middle'), destra ('end')
    color='#007a53'
)
chart
Out[8]:
In [9]:
chart.save("grafico.png", output_width=1280, output_height=720)

base 100¶

In [10]:
df1['period'] = pd.to_datetime(df1['period'])
valore_base_2019 = df1.loc[df1['period'] == '2019-01-01', 'value'].values[0]
df1['base100_2019'] = df1['value'] / valore_base_2019 * 100
In [11]:
chart = alt.Chart(df1).mark_line(
    color='#FF0000',    strokeWidth=3
).encode(
    x=alt.X('period:T', title=None, axis=alt.Axis(labelFlush=False)),
    y=alt.Y('base100_2019:Q', title='Indice', scale=alt.Scale(zero=False)),  # <-- scala automatica
    tooltip=['period:T', 'base100_2019:Q']
).properties(    width=900,    height=300,
    title='Evoluzione della Variabile a Base 100 (Q1 2019)'
).configure_title(    font='Helvetica Neue',    fontSize=20,    anchor='start',    color='#333')
chart
Out[11]:
In [12]:
df1[df1['period'] >= '2023-10-01'][['period', 'value', 'base100_2019']]
Out[12]:
period value base100_2019
115 2023-10-01 389086.6 104.853389
116 2024-01-01 390412.3 105.210646
117 2024-04-01 390708.1 105.290360
118 2024-07-01 390755.2 105.303053
119 2024-10-01 391285.0 105.445827

[A.EUR_​HAB.ITF6] Annual – Euro per inhabitant – Calabria¶

In [13]:
df1 = fetch_series('Eurostat/NAMA_10R_3GDP/A.EUR_HAB.ITF6')
In [14]:
chart = Chart(df1[df1.value.notna()]).mark_line(
    color='#007A53',strokeWidth=3
).encode(
    x=alt.X('period:T', title=None, axis=alt.Axis(labelFlush=False)),
    y=alt.Y('value:Q', scale=alt.Scale(zero=False), title=None),
    tooltip=['period:T', 'value:Q']
).properties(
    width=800, height=300, title='Prodotto interno lordo' 
).configure_title(
    font='Calibri',fontSize=22,anchor='start',     # allinea a sinistra ('start'), centro ('middle'), destra ('end')
    color='#007a53'
)
chart
Out[14]:
In [15]:
# https://it.wikipedia.org/wiki/Nomenclatura_delle_unit%C3%A0_territoriali_per_le_statistiche_dell%27Italia
df2 = fetch_series([
    'Eurostat/NAMA_10R_3GDP/A.EUR_HAB.ITC', # NOvest
    'Eurostat/NAMA_10R_3GDP/A.EUR_HAB.ITH', # NEst
    'Eurostat/NAMA_10R_3GDP/A.EUR_HAB.ITI', # Centro
    'Eurostat/NAMA_10R_3GDP/A.EUR_HAB.ITF', # Sud
    'Eurostat/NAMA_10R_3GDP/A.EUR_HAB.ITG', # isole
])
In [16]:
# oppure
# === Dizionario regioni e codici ===
region_codes = {
    "NOvest": "ITC",
    "NEst": "ITH",
    "Centro": "ITI",
    "Sud": "ITF",
    "Isole": "ITG"
}

# === Costruzione della lista di codici ===
series_list = [f'Eurostat/NAMA_10R_3GDP/A.EUR_HAB.{code}' for code in region_codes.values()]

# === Fetch ===
df1 = fetch_series(series_list)
In [17]:
chart = Chart(df2.query("period >= '1900'")).mark_line().encode(
    x=alt.X('period:T', title=None, axis=alt.Axis(labelFlush=False)),
    y=Y('value', scale=Scale(zero=False)),
    color='series_code',
).properties(
    width=500, height=300, title='PIL pro capite' 
).configure_title(
    font='Calibri',fontSize=22,anchor='start',     # allinea a sinistra ('start'), centro ('middle'), destra ('end')
    color='#007a53'
)
chart
Out[17]:
In [18]:
# === Unico dizionario centrale: nome regione → codice ===
regioni = {
    "Nord-Ovest": "ITC",
    "Nord-Est": "ITH",
    "Centro": "ITI",
    "Sud": "ITF",
    "Isole": "ITG"
}

# === Costruzione lista delle serie da fetchare ===
series_list = [f'Eurostat/NAMA_10R_3GDP/A.EUR_HAB.{codice}' for codice in regioni.values()]

# === Fetch dati ===
df2 = fetch_series(series_list)

# === Mappa codice → nome leggibile (usando il dizionario invertito) ===
codice_to_nome = {v: k for k, v in regioni.items()}
df2["Regione"] = df2["series_code"].map(lambda s: codice_to_nome.get(s.split(".")[-1], s))

# === Grafico Altair ===
chart = Chart(df2.query("period >= '1900'")).mark_line().encode(
    x=alt.X('period:T', title=None, axis=alt.Axis(labelFlush=False)),
    y=Y('value', scale=Scale(zero=False)),
    color=alt.Color('Regione:N', title=""),
).properties(
    width=500, height=300, title='PIL pro capite'
).configure_title(
    font='Calibri', fontSize=22, anchor='start',
    color='#007a53'
)

chart
Out[18]:
In [19]:
# Raggruppa le regioni in macroaree
macro_map = {
    'ITC': 'Centro-Nord',
    'ITH': 'Centro-Nord',
    'ITI': 'Centro-Nord',
    'ITF': 'Mezzogiorno',
    'ITG': 'Mezzogiorno'
}

df2['area'] = df2['geo'].map(macro_map)

# Calcola la media per area e periodo
df_macro = (
    df2.groupby(['period', 'area'])['value']
    .mean()
    .reset_index()
    .pivot(index='period', columns='area', values='value')
    .reset_index()
)

# Trasforma il df da wide a long
df_long = df_macro.melt(id_vars='period', var_name='series_code', value_name='value')

# Filtro solo dal 2019 in poi
chart = alt.Chart(df_long.query("period >= '1900'")).mark_line().encode(
    x=alt.X('period:T', title=None, axis=alt.Axis(labelFlush=False)),
    y=alt.Y('value:Q', scale=alt.Scale(zero=False)),
    color='series_code:N',
).properties(
    title="PIL pro capite – Centro-Nord vs Mezzogiorno"
)

chart
Out[19]:
In [20]:
UE = {
    "Austria": "AT","Belgium": "BE","Bulgaria": "BG","Croatia": "HR","Cyprus": "CY","Czechia": "CZ","Denmark": "DK","Estonia": "EE",
    "Finland": "FI","France": "FR","Germany": "DE","Greece": "EL","Hungary": "HU","Ireland": "IE","Italy": "IT","Latvia": "LV","Lithuania": "LT",
    "Luxembourg": "LU","Malta": "MT","Netherlands": "NL","Poland": "PL","Portugal": "PT","Romania": "RO","Slovakia": "SK","Slovenia": "SI",
    "Spain": "ES","Sweden": "SE", "United Kingdom":"UK"
}

regioni = { # usare NAMA_10R_3GDP per le province trenine oppure NAMA_10R_2GDP e ITH1 per Trentino
    "Piemonte": "ITC1", "Valle d'Aosta": "ITC2", "Liguria": "ITC3", "Lombardia": "ITC4",
    "Provincia Autonoma di Bolzano": "ITH10", "Provincia Autonoma di Trento": "ITH20",
    "Veneto": "ITH3", "Friuli-Venezia Giulia": "ITH4", "Emilia-Romagna": "ITH5",    
    "Toscana": "ITI1","Umbria": "ITI2", "Marche": "ITI3", "Lazio": "ITI4",
    "Abruzzo": "ITF1", "Molise": "ITF2", "Campania": "ITF3", "Puglia": "ITF4", "Basilicata": "ITF5", "Calabria": "ITF6",
    "Sicilia": "ITG1", "Sardegna": "ITG2"
}

puglia = {"Bari":"ITF47","Barletta-Andria-Trani":"ITF45","Brindisi":"ITF44","Foggia":"ITF41","Lecce":"ITF46","Taranto":"ITF43"}
In [21]:
# https://it.wikipedia.org/wiki/Nomenclatura_delle_unit%C3%A0_territoriali_per_le_statistiche_dell%27Italia
from dbnomics import fetch_series
import pandas as pd
selezione = regioni
#series_codes = [f'Eurostat/NAMA_10_GDP/A.CP_MEUR.B1GQ.{code}' for code in selezione.values()] #PIL M€
series_codes = [f'Eurostat/NAMA_10R_3GDP/A.EUR_HAB.{code}' for code in selezione.values()] #PIL M€
df2 = fetch_series(series_codes) # === Fetch con dbnomics ===
code_to_name = {v: k for k, v in selezione.items()}
df2["Regione"] = df2["series_code"].map(lambda s: code_to_name.get(s.split(".")[-1], s))
df2["value"] = pd.to_numeric(df2["value"], errors="coerce")
In [22]:
df2["period"] = pd.to_datetime(df2["period"]).dt.year  # estrai solo l'anno
pivot_df = df2.pivot_table(index="Regione",columns="period",values="value").sort_index()
pivot_df = pivot_df.reset_index() # Opzionale: reset per renderlo più compatibile con CSV/Excel
In [23]:
pivot_df.sort_values(by=2019, ascending=False) # [['Regione',2019]]
Out[23]:
period Regione 2000 2001 2002 2003 2004 2005 2006 2007 2008 ... 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023
12 Provincia Autonoma di Bolzano 31300.0 32200.0 32500.0 33500.0 35300.0 35600.0 37300.0 38600.0 39300.0 ... 42900.0 43600.0 44300.0 45600.0 47300.0 48400.0 44900.0 49800.0 56000.0 NaN
8 Lombardia 28900.0 30300.0 31500.0 32300.0 33000.0 33600.0 34400.0 35600.0 36600.0 ... 35700.0 36400.0 37400.0 38400.0 39400.0 39700.0 37300.0 42500.0 45900.0 49000.0
13 Provincia Autonoma di Trento 29400.0 30700.0 31300.0 32000.0 32600.0 33000.0 34000.0 35300.0 35400.0 ... 36100.0 35900.0 36400.0 37100.0 38500.0 39400.0 37100.0 39400.0 43900.0 NaN
19 Valle d'Aosta 28900.0 30400.0 31300.0 33400.0 34000.0 34800.0 35900.0 36600.0 37500.0 ... 36300.0 36500.0 36300.0 37800.0 38300.0 38800.0 35800.0 38700.0 44000.0 46300.0
4 Emilia-Romagna 26800.0 27800.0 28500.0 29000.0 29900.0 30500.0 31900.0 33200.0 33200.0 ... 32900.0 33500.0 34500.0 35500.0 36200.0 36500.0 34100.0 38100.0 40700.0 43300.0
6 Lazio 27000.0 28700.0 30100.0 30800.0 32500.0 33100.0 34000.0 35100.0 34700.0 ... 32300.0 32300.0 33500.0 34000.0 34500.0 35000.0 32400.0 35700.0 39800.0 41700.0
20 Veneto 24800.0 25600.0 26100.0 27100.0 28200.0 28700.0 29500.0 30500.0 30200.0 ... 30100.0 30800.0 31900.0 32800.0 33400.0 34000.0 31300.0 35000.0 38000.0 40600.0
17 Toscana 23100.0 24200.0 25000.0 25700.0 26500.0 26900.0 27900.0 28900.0 28900.0 ... 29100.0 29400.0 30200.0 30900.0 31700.0 33000.0 29200.0 32500.0 35600.0 37600.0
7 Liguria 23100.0 24700.0 25000.0 26000.0 26900.0 27600.0 28500.0 30100.0 30700.0 ... 29600.0 30200.0 30900.0 31800.0 32100.0 32800.0 29700.0 32700.0 35400.0 38000.0
5 Friuli-Venezia Giulia 23600.0 24800.0 25400.0 25500.0 26300.0 27300.0 28500.0 29600.0 29200.0 ... 28700.0 29600.0 30100.0 30800.0 31800.0 32600.0 30400.0 33800.0 35800.0 37700.0
11 Piemonte 23600.0 24700.0 25500.0 26300.0 27100.0 27800.0 28800.0 29500.0 29400.0 ... 28200.0 28900.0 29700.0 30800.0 31600.0 31900.0 29500.0 32200.0 34500.0 36700.0
9 Marche 20600.0 21800.0 22900.0 23300.0 24100.0 24600.0 25900.0 26800.0 26400.0 ... 25600.0 25900.0 26500.0 27200.0 27700.0 28300.0 26300.0 28900.0 31100.0 33200.0
18 Umbria 21500.0 22600.0 23000.0 23600.0 24300.0 24600.0 25700.0 26400.0 26500.0 ... 23700.0 24400.0 24600.0 25300.0 26200.0 26500.0 24400.0 26700.0 28800.0 30500.0
0 Abruzzo 19100.0 20000.0 20400.0 20600.0 20500.0 21500.0 22400.0 23200.0 23600.0 ... 23800.0 24100.0 24300.0 25000.0 25300.0 25600.0 23700.0 26300.0 28600.0 31000.0
1 Basilicata 16400.0 16900.0 17500.0 17500.0 18100.0 18400.0 19600.0 20500.0 20500.0 ... 19800.0 21600.0 21700.0 22000.0 23300.0 23200.0 21200.0 23900.0 25800.0 27500.0
15 Sardegna 15300.0 16200.0 16600.0 17300.0 18100.0 18500.0 19200.0 19800.0 20300.0 ... 19700.0 20500.0 20400.0 20900.0 21300.0 21900.0 20400.0 22500.0 24500.0 26300.0
10 Molise 16800.0 17800.0 18200.0 18600.0 19300.0 19900.0 21200.0 22100.0 21700.0 ... 19300.0 19700.0 20000.0 20600.0 21100.0 21800.0 20600.0 23400.0 25000.0 26700.0
14 Puglia 14300.0 15000.0 15400.0 15700.0 16200.0 16500.0 17200.0 17500.0 17300.0 ... 17400.0 17800.0 18300.0 18600.0 19100.0 19500.0 18400.0 20200.0 22000.0 23500.0
3 Campania 14500.0 15400.0 16000.0 16300.0 16800.0 17200.0 17800.0 18400.0 18500.0 ... 17400.0 17900.0 18200.0 18700.0 19000.0 19400.0 18100.0 19900.0 21800.0 23300.0
16 Sicilia 13900.0 14700.0 15200.0 15700.0 16100.0 16900.0 17500.0 17800.0 18000.0 ... 16800.0 17200.0 17400.0 17800.0 18000.0 18300.0 17300.0 19100.0 21200.0 22900.0
2 Calabria 13000.0 13700.0 14100.0 14600.0 15300.0 15800.0 16400.0 16900.0 17100.0 ... 16300.0 16500.0 16800.0 17300.0 17300.0 17600.0 16600.0 18400.0 19700.0 21100.0

21 rows × 25 columns

In [24]:
col_regione = pivot_df.columns[0]
df_base100 = pivot_df.copy()

# Calcolo base 100 rispetto alla media nazionale per ciascun anno (colonna)
for col in pivot_df.columns[1:]:
    media_italia = pivot_df[col].mean(skipna=True)
    df_base100[col] = pivot_df[col] / media_italia * 100
# Colonne temporali da selezionare
anni = [2000, 2008, 2013, 2018, 2023]

# Nome colonna che contiene le regioni
col_regione = df_base100.columns[0]

# Seleziona solo la colonna delle regioni + range 2012–2017
df_base100_range = df_base100[[col_regione] + anni]
df_base100_range[anni] = df_base100_range[anni].applymap(lambda x: f'{x:,.1f}' if pd.notnull(x) else '')
df_base100_range.sort_values(by=2023, ascending=True)
# df_base100_range.to_csv("base100_2012_2017.csv", index=False)
# df_base100.to_csv("pil_base100.csv", index=False)
C:\Users\paolo\AppData\Local\Temp\ipykernel_25596\1004001006.py:16: FutureWarning: DataFrame.applymap has been deprecated. Use DataFrame.map instead.
  df_base100_range[anni] = df_base100_range[anni].applymap(lambda x: f'{x:,.1f}' if pd.notnull(x) else '')
C:\Users\paolo\AppData\Local\Temp\ipykernel_25596\1004001006.py:16: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  df_base100_range[anni] = df_base100_range[anni].applymap(lambda x: f'{x:,.1f}' if pd.notnull(x) else '')
Out[24]:
period Regione 2000 2008 2013 2018 2023
12 Provincia Autonoma di Bolzano 144.2 143.5 160.0 162.0
13 Provincia Autonoma di Trento 135.4 129.3 135.9 131.9
11 Piemonte 108.7 107.4 105.9 108.2 109.5
17 Toscana 106.4 105.5 107.0 108.6 112.2
5 Friuli-Venezia Giulia 108.7 106.6 107.0 108.9 112.5
7 Liguria 106.4 112.1 108.5 109.9 113.4
20 Veneto 114.2 110.3 111.5 114.4 121.1
6 Lazio 124.4 126.7 121.3 118.2 124.4
4 Emilia-Romagna 123.4 121.3 121.3 124.0 129.2
19 Valle d'Aosta 133.1 137.0 137.1 131.2 138.1
8 Lombardia 133.1 133.7 132.2 135.0 146.2
2 Calabria 59.9 62.5 61.6 59.3 62.9
16 Sicilia 64.0 65.7 64.2 61.7 68.3
3 Campania 66.8 67.6 65.0 65.1 69.5
14 Puglia 65.9 63.2 64.6 65.4 70.1
15 Sardegna 70.5 74.1 73.6 73.0 78.5
10 Molise 77.4 79.3 72.9 72.3 79.7
1 Basilicata 75.5 74.9 77.0 79.8 82.0
18 Umbria 99.0 96.8 90.1 89.7 91.0
0 Abruzzo 88.0 86.2 89.4 86.7 92.5
9 Marche 94.9 96.4 93.9 94.9 99.0
In [25]:
import altair as alt
from vega_datasets import data
source = data.stocks()

alt.Chart(source).mark_area(
    color="lightblue",
    interpolate='step-after',
    line=True
).encode(
    x='date',
    y='price'
).transform_filter(alt.datum.symbol == 'GOOG')
Out[25]:
In [ ]:
 
In [ ]: