In [1]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import os
import geopandas as gpd
from sklearn.preprocessing import MinMaxScaler
from shapely import wkt
from jenkspy import jenks_breaks

plt.style.use('seaborn-v0_8-whitegrid')
sns.set_palette('viridis')

Edilizia residenziale pubblica e sociale¶

Dati¶

In [2]:
ilab_path = os.path.join(os.path.expanduser('~'), 'ILAB_DATA')
work_path = os.path.join(ilab_path, 'PATRIMONIO', 'DATA')
out_path = os.path.join(ilab_path, 'PATRIMONIO', 'OUT')
In [3]:
resolution = 8
In [4]:
file_path = os.path.join(out_path, f"grid_{resolution:02}_adv.csv")
df = pd.read_csv(file_path)
print(f"Dataset caricato con {df.shape[0]} righe e {df.shape[1]} colonne")
Dataset caricato con 2286 righe e 336 colonne
In [5]:
# Convertiamo le colonne numeriche che potrebbero essere stringhe
for col in df:
    if df[col].dtype == 'object' and col != 'geometry' and col != f'h3_{resolution:02}':
        try:
            df[col] = pd.to_numeric(df[col], errors='coerce')
        except:
            pass
In [6]:
# Creiamo un GeoDataFrame se è presente la colonna geometry
if 'geometry' in df.columns:
    try:
        df['geometry'] = df['geometry'].apply(wkt.loads)
        gdf = gpd.GeoDataFrame(df, geometry='geometry', crs=32632)
        print("Dati convertiti in formato geospaziale")
    except Exception as e:
        print(f"Errore nella conversione in GeoDataFrame: {e}")
        gdf = None
else:
    print("Colonna 'geometry' non trovata, utilizzo DataFrame standard")
    gdf = None
Dati convertiti in formato geospaziale

Dati demografici¶

In [7]:
# Verifichiamo i dati demografici disponibili
demographic_cols = [col for col in df if 'ISTAT||P' in col]
recent_demographic_cols = [col for col in demographic_cols if '__21' in col]

print(f"Colonne demografiche recenti disponibili: {len(recent_demographic_cols)}")
recent_demographic_cols
Colonne demografiche recenti disponibili: 9
Out[7]:
['ISTAT||POP_F__21',
 'ISTAT||POP_M__21',
 'ISTAT||POP_TOT__21',
 'ISTAT||P_0_14__21',
 'ISTAT||P_15_19__21',
 'ISTAT||P_20_39__21',
 'ISTAT||P_40_64__21',
 'ISTAT||P_65_99__21',
 'ISTAT||POP_TOT__21__11']

Densità abitativa¶

In [8]:
# Calcoliamo la densità abitativa se è disponibile la superficie della cella
df['densita_abitativa'] = df['ISTAT||POP_TOT__21'] / (df['cell_a_m2'] / 1000000)  # abitanti per km²
In [9]:
gdf['densita_abitativa'] = df['densita_abitativa']

Dati reddito¶

In [10]:
# Verifichiamo la presenza di dati sul reddito
income_cols = [col for col in df if 'redd' in col.lower()]
print("Colonne relative al reddito:")
income_cols
Colonne relative al reddito:
Out[10]:
['reddito_pro_capite||redd_cell', 'reddito_pro_capite||redd_pc']
In [11]:
# Calcoliamo statistiche rilevanti
for col in income_cols:
    try:
        df[col] = pd.to_numeric(df[col], errors='coerce')
        print(f"\nStatistiche per {col}:")
        print(df[col].describe())
    except:
        print(f"Non è stato possibile convertire {col} in numerico")
Statistiche per reddito_pro_capite||redd_cell:
count    1.327000e+03
mean     3.968004e+07
std      7.190108e+07
min      0.000000e+00
25%      3.870650e+05
50%      5.242034e+06
75%      4.597777e+07
max      5.085921e+08
Name: reddito_pro_capite||redd_cell, dtype: float64

Statistiche per reddito_pro_capite||redd_pc:
count     1281.000000
mean     18444.072738
std       7232.305257
min          0.000000
25%      13298.879827
50%      18157.726319
75%      22077.113347
max      46494.359458
Name: reddito_pro_capite||redd_pc, dtype: float64

Dati sull'uso del suolo¶

In [12]:
# Verifichiamo la presenza di dati sull'uso del suolo
land_use_cols = [col for col in df if 'CLC||' in col and col not in ['CLC||LABEL', 'CLC||int_a_m2', 'CLC||perc']]
print(f"Colonne sull'uso del suolo: {len(land_use_cols)}")
print(land_use_cols)
Colonne sull'uso del suolo: 7
['CLC||Agricultural', 'CLC||Artificial, non-agricultural vegetated', 'CLC||Forest and semi natural', 'CLC||Industrial, commercial and transport', 'CLC||Mine, dump and construction', 'CLC||Urban', 'CLC||Water bodies']

Indice di urbanizzazione¶

In [13]:
# Calcoliamo le percentuali di uso del suolo
for col in land_use_cols:
    categoria = col.replace('CLC||', '')
    categoria_norm = categoria.lower().replace(' and ', '_').replace(' ', '_')
    
    # Convertiamo a numerico per evitare operazioni tra stringhe e numeri
    df[col] = pd.to_numeric(df[col], errors='coerce')
    df['cell_a_m2'] = pd.to_numeric(df['cell_a_m2'], errors='coerce')
    
    # Evitiamo divisione per zero
    df[f'perc_{categoria_norm}'] = np.where(df['cell_a_m2'] > 0, 
                                        df[col] / df['cell_a_m2'] * 100,
                                        0)
In [14]:
# Calcoliamo l'indice di urbanizzazione
df['indice_urbanizzazione'] = np.where(df['cell_a_m2'] > 0,
                                        df['CLC||Urban'] / df['cell_a_m2'] * 100,
                                        0)

plt.figure(figsize=(10, 6))
sns.histplot(df['indice_urbanizzazione'].clip(0, 100), bins=30)
plt.title('Distribuzione dell\'indice di urbanizzazione')
plt.xlabel('Percentuale di area urbanizzata')
plt.ylabel('Numero di celle')
plt.show()
No description has been provided for this image

Dati sull'accessibilità ai servizi¶

In [15]:
servizi_cittadinanza = ['infrastrutture', 'cultura', 'istruzione', 'sanita', 'sport']

access_cols = []
for col in df:
    for servizio in servizi_cittadinanza:
        if servizio in col:
            access_cols.append(col)

Indice di accessibilità ai servizi¶

In [16]:
# Calcoliamo indici di accessibilità
df['accessibilita_15min'] = df[[col for col in access_cols if '15' in col]].mean(axis=1)
df['accessibilita_30min'] = df[[col for col in access_cols if '30' in col]].mean(axis=1)
In [17]:
# Calcoliamo un indice composito di accessibilità
df['indice_accessibilita'] = (df['accessibilita_15min'] * 2 + df['accessibilita_30min']) / 3

Indice composito di fabbisogno abitativo¶

Definiamo prima i componenti che potrebbero contribuire al fabbisogno abitativo

  1. Componente demografica (densità abitativa e invecchiamento)
In [18]:
# Calcoliamo indice di invecchiamento se disponibili i dati
if 'ISTAT||P_65_99__21' in df.columns and 'ISTAT||P_0_14__21' in df.columns:
    df['ISTAT||P_65_99__21'] = pd.to_numeric(df['ISTAT||P_65_99__21'], errors='coerce').fillna(0)
    df['ISTAT||P_0_14__21'] = pd.to_numeric(df['ISTAT||P_0_14__21'], errors='coerce').fillna(0)
    df['indice_invecchiamento'] = np.where(df['ISTAT||P_0_14__21'] > 0,
                                         df['ISTAT||P_65_99__21'] / df['ISTAT||P_0_14__21'] * 100,
                                         0)
    df['indice_invecchiamento'] = df['indice_invecchiamento'].clip(0, 500)
  1. Componente economica (reddito)
In [19]:
if 'reddito_pro_capite||redd_pc' in df.columns:
    df['reddito_pc'] = pd.to_numeric(df['reddito_pro_capite||redd_pc'], errors='coerce').fillna(0)
In [20]:
# Normalizziamo le variabili per l'indice composito
features_for_index = []

if 'densita_abitativa' in df.columns:
    features_for_index.append('densita_abitativa')
if 'indice_invecchiamento' in df.columns:
    features_for_index.append('indice_invecchiamento')
if 'reddito_pc' in df.columns:
    features_for_index.append('reddito_pc')
if 'indice_urbanizzazione' in df.columns:
    features_for_index.append('indice_urbanizzazione')
if 'indice_accessibilita' in df.columns:
    features_for_index.append('indice_accessibilita')
In [21]:
# Creiamo una copia dei dati selezionati e rimuoviamo i valori NaN
df_index = df[features_for_index].copy()
df_index = df_index.fillna(0)

# Normalizziamo le variabili (min-max scaling)
scaler = MinMaxScaler()
df_scaled = pd.DataFrame(scaler.fit_transform(df_index),
                        columns=features_for_index,
                        index=df_index.index)
In [22]:
# Invertiamo il reddito (meno reddito = più bisogno)
if 'reddito_pc' in df_scaled.columns:
    df_scaled['reddito_pc_inv'] = 1 - df_scaled['reddito_pc']
    df_scaled = df_scaled.drop('reddito_pc', axis=1)
    features_for_index = [col for col in df_scaled.columns if col != 'reddito_pc'] + ['reddito_pc_inv']

Calcoliamo l'indice di fabbisogno abitativo¶

Alta densità + alto invecchiamento + basso reddito + alta urbanizzazione + alta accessibilità

In [23]:
weights = {}
for feat in features_for_index:
    if 'densita_abitativa' in feat:
        weights[feat] = 0.2  # Peso positivo per densità
    elif 'invecchiamento' in feat:
        weights[feat] = 0.15  # Peso positivo per invecchiamento
    elif 'reddito_pc_inv' in feat:
        weights[feat] = 0.3  # Peso alto per reddito inverso (basso reddito)
    elif 'urbanizzazione' in feat:
        weights[feat] = 0.15  # Peso per urbanizzazione
    elif 'accessibilita' in feat:
        weights[feat] = 0.2  # Peso per accessibilità

Calcoliamo l'indice composito di fabbisogno abitativo

In [24]:
df_scaled['indice_fabbisogno_abitativo'] = sum(df_scaled[feat] * weights[feat] for feat in features_for_index)
In [25]:
# Riportiamo l'indice al DataFrame originale
df.loc[df_scaled.index, 'indice_fabbisogno_abitativo'] = df_scaled['indice_fabbisogno_abitativo']
In [26]:
# Classifichiamo il fabbisogno in categorie
df['classe_fabbisogno'] = pd.qcut(
    df['indice_fabbisogno_abitativo'].dropna(), 
    q=5, 
    labels=['Molto basso', 'Basso', 'Medio', 'Alto', 'Molto alto']
)
In [27]:
# Visualizziamo la distribuzione dell'indice
plt.figure(figsize=(10, 6))
sns.histplot(df['indice_fabbisogno_abitativo'].dropna(), bins=30)
plt.title('Distribuzione dell\'indice di fabbisogno abitativo')
plt.xlabel('Indice di fabbisogno')
plt.ylabel('Numero di celle')
plt.show()
No description has been provided for this image

Indice di priorità per edilizia residenziale sociale/pubblica¶

Consideriamo: densità, reddito, accessibilità, indice di fabbisogno

In [28]:
features_for_erp = []

if 'indice_fabbisogno_abitativo' in df.columns:
    features_for_erp.append('indice_fabbisogno_abitativo')
if 'densita_abitativa' in df.columns:
    features_for_erp.append('densita_abitativa')
if 'reddito_pc' in df.columns:
    features_for_erp.append('reddito_pc')
if 'indice_accessibilita' in df.columns:
    features_for_erp.append('indice_accessibilita')
In [29]:
# Creiamo una copia dei dati selezionati e rimuoviamo i valori NaN
df_erp = df[features_for_erp].copy()
df_erp = df_erp.fillna(0)

# Normalizziamo le variabili (min-max scaling)
scaler = MinMaxScaler()
df_scaled_erp = pd.DataFrame(scaler.fit_transform(df_erp), 
                            columns=features_for_erp,
                            index=df_erp.index)

Invertiamo il reddito (meno reddito = più priorità)

In [30]:
if 'reddito_pc' in df_scaled_erp.columns:
    df_scaled_erp['reddito_pc_inv'] = 1 - df_scaled_erp['reddito_pc']
    df_scaled_erp = df_scaled_erp.drop('reddito_pc', axis=1)
    features_for_erp = [col for col in df_scaled_erp.columns if col != 'reddito_pc'] + ['reddito_pc_inv']

Calcoliamo l'indice di priorità per edilizia residenziale pubblica

In [31]:
weights_erp = {}
for feat in features_for_erp:
    if 'fabbisogno' in feat:
        weights_erp[feat] = 0.4  # Peso alto per fabbisogno
    elif 'densita_abitativa' in feat:
        weights_erp[feat] = 0.2  # Peso per densità
    elif 'reddito_pc_inv' in feat:
        weights_erp[feat] = 0.3  # Peso per reddito inverso
    elif 'accessibilita' in feat:
        weights_erp[feat] = 0.1  # Peso basso per accessibilità
In [32]:
df_scaled_erp['indice_priorita_erp'] = sum(df_scaled_erp[feat] * weights_erp[feat] 
                                        for feat in features_for_erp)
In [33]:
# Riportiamo l'indice al DataFrame originale
df.loc[df_scaled_erp.index, 'indice_priorita_erp'] = df_scaled_erp['indice_priorita_erp']

# Classifichiamo la priorità in categorie
df['classe_priorita_erp'] = pd.qcut(
    df['indice_priorita_erp'].dropna(), 
    q=5, 
    labels=['Priorità molto bassa', 'Priorità bassa', 'Priorità media', 'Priorità alta', 'Priorità molto alta']
)
In [34]:
# Visualizziamo la distribuzione dell'indice di priorità
plt.figure(figsize=(10, 6))
sns.histplot(df['indice_priorita_erp'].dropna(), bins=30)
plt.title('Distribuzione dell\'indice di priorità per edilizia residenziale sociale')
plt.xlabel('Indice di priorità')
plt.ylabel('Numero di celle')
plt.show()
No description has been provided for this image
In [35]:
gdf_with_index = gdf.copy()
In [36]:
gdf_with_index.loc[df_scaled_erp.index, 'indice_priorita_erp'] = df_scaled_erp['indice_priorita_erp']

# fig, ax = plt.subplots(figsize=(12, 8))
# gdf_with_index.dropna(subset=['indice_priorita_erp']).plot(
#     column='indice_priorita_erp', 
#     cmap='RdYlGn_r', 
#     legend=True, 
#     ax=ax
# )
# plt.title('Indice di priorità per edilizia residenziale sociale')
# plt.axis('off')
# plt.show()
In [37]:
gdf_with_index['classe_priorita_erp'] = df['classe_priorita_erp']

fig, ax = plt.subplots(figsize=(12, 8))
gdf_with_index.dropna(subset=['classe_priorita_erp']).plot(
    column='classe_priorita_erp', 
    cmap='RdYlGn_r', 
    categorical=True,
    legend=True, 
    ax=ax
)
plt.title('Classi di priorità per edilizia residenziale sociale')
plt.axis('off')
plt.show()
No description has been provided for this image

Indice di equilibrio sociale dell'edilizia residenziale¶

Consideriamo: mix di età, mix di reddito, accessibilità, presenza di servizi

Calcoliamo la diversità di età (Gini-Simpson index)¶

In [38]:
age_groups = [col for col in recent_demographic_cols if 'ISTAT||P_' in col]

# Convertiamo tutte le colonne demografiche in numeriche
for col in age_groups:
    df[col] = pd.to_numeric(df[col], errors='coerce').fillna(0)

# Calcoliamo le proporzioni di ogni gruppo di età
df_age_props = df[age_groups].div(df[age_groups].sum(axis=1), axis=0)

# Calcoliamo l'indice di diversità (più alto = più diversità)
df['indice_diversita_eta'] = 1 - (df_age_props ** 2).sum(axis=1)
In [39]:
# Visualizziamo la distribuzione dell'indice di diversità di età
plt.figure(figsize=(10, 6))
sns.histplot(df['indice_diversita_eta'].dropna(), bins=30)
plt.title('Distribuzione dell\'indice di diversità di età')
plt.xlabel('Indice di diversità')
plt.ylabel('Numero di celle')
plt.show()
No description has been provided for this image

Calcoliamo l'indice composito di equilibrio sociale¶

In [40]:
features_for_balance = [
    'indice_diversita_eta', 
    'indice_accessibilita',
    'reddito_pc'
]

# Creiamo una copia dei dati selezionati e rimuoviamo i valori NaN
df_balance = df[features_for_balance].copy()
df_balance = df_balance.fillna(0)
In [41]:
# Normalizziamo le variabili (min-max scaling)
scaler = MinMaxScaler()
df_scaled_balance = pd.DataFrame(scaler.fit_transform(df_balance), 
                                columns=features_for_balance,
                                index=df_balance.index)
In [42]:
weights_balance = {}
for feat in features_for_balance:
    if 'diversita_eta' in feat:
        weights_balance[feat] = 0.4  # Peso alto per diversità età
    elif 'accessibilita' in feat:
        weights_balance[feat] = 0.4  # Peso alto per accessibilità
    elif 'reddito_pc' in feat:
        weights_balance[feat] = 0.2  # Peso per reddito (qui consideriamo positivo un reddito alto per mixité)
In [43]:
df_scaled_balance['indice_equilibrio_sociale'] = sum(df_scaled_balance[feat] * weights_balance[feat] 
                                                    for feat in features_for_balance)
In [44]:
# Riportiamo l'indice al DataFrame originale
df.loc[df_scaled_balance.index, 'indice_equilibrio_sociale'] = df_scaled_balance['indice_equilibrio_sociale']
In [45]:
# Classifichiamo l'equilibrio in categorie
df['classe_equilibrio_sociale'] = pd.qcut(
    df['indice_equilibrio_sociale'].dropna(), 
    q=5, 
    labels=['Molto basso', 'Basso', 'Medio', 'Alto', 'Molto alto']
)
In [46]:
# Visualizziamo la distribuzione dell'indice di equilibrio sociale
plt.figure(figsize=(10, 6))
sns.histplot(df['indice_equilibrio_sociale'].dropna(), bins=30)
plt.title('Distribuzione dell\'indice di equilibrio sociale')
plt.xlabel('Indice di equilibrio')
plt.ylabel('Numero di celle')
plt.show()
No description has been provided for this image

Conclusioni¶

Correlazione tra gli indici¶

In [47]:
# Vediamo la correlazione tra essi
indices = [col for col in df.columns if 'indice_' in col]
correlation = df[indices].corr()

plt.figure(figsize=(10, 8))
sns.heatmap(correlation, annot=True, cmap='coolwarm', vmin=-1, vmax=1)
plt.title('Correlazione tra gli indici compositi')
plt.tight_layout()
plt.show()
No description has been provided for this image

Creiamo un riepilogo dei risultati degli indici per la presentazione¶

In [48]:
# Individuiamo le aree con alta priorità
high_priority = df[df['classe_priorita_erp'].isin(['Priorità alta', 'Priorità molto alta'])].copy()
In [49]:
# Calcoliamo statistiche descrittive per queste aree
print("\n===== AREE AD ALTA PRIORITÀ PER EDILIZIA RESIDENZIALE SOCIALE =====")
print(f"Numero totale di aree ad alta priorità: {len(high_priority)}")

if 'densita_abitativa' in high_priority.columns:
    print(f"Densità abitativa media: {high_priority['densita_abitativa'].mean():.2f} abitanti/km²")

if 'indice_invecchiamento' in high_priority.columns:
    print(f"Indice di invecchiamento medio: {high_priority['indice_invecchiamento'].mean():.2f}")

if 'reddito_pc' in high_priority.columns:
    print(f"Reddito pro capite medio: {high_priority['reddito_pc'].mean():.2f}")

if 'indice_accessibilita' in high_priority.columns:
    print(f"Indice di accessibilità medio: {high_priority['indice_accessibilita'].mean():.2f}")

if 'indice_urbanizzazione' in high_priority.columns:
    print(f"Indice di urbanizzazione medio: {high_priority['indice_urbanizzazione'].mean():.2f}%")
===== AREE AD ALTA PRIORITÀ PER EDILIZIA RESIDENZIALE SOCIALE =====
Numero totale di aree ad alta priorità: 914
Densità abitativa media: 1050.08 abitanti/km²
Indice di invecchiamento medio: 91.23
Reddito pro capite medio: 866.25
Indice di accessibilità medio: 27.53
Indice di urbanizzazione medio: 13.31%
In [50]:
# Considerazioni finali sugli indicatori compositi ottenuti

# Riassunto degli indicatori calcolati
print("\n===== CONSIDERAZIONI FINALI SUGLI INDICATORI COMPOSITI =====")

print("\nIndicatori principali sviluppati:")
for indicator in [col for col in df.columns if 'indice_' in col]:
   valid_values = df[indicator].dropna()
   if len(valid_values) > 0:
       print(f"- {indicator}: {len(valid_values)} valori validi")
       print(f"  Min: {valid_values.min():.4f}, Max: {valid_values.max():.4f}, Media: {valid_values.mean():.4f}")

# Aree ad alta priorità per interventi di edilizia residenziale
high_priority_areas = None
if 'classe_priorita_erp_servizi' in df.columns:
   high_priority_areas = df[df['classe_priorita_erp_servizi'].isin(['Priorità alta', 'Priorità molto alta'])]
elif 'classe_priorita_erp' in df.columns:
   high_priority_areas = df[df['classe_priorita_erp'].isin(['Priorità alta', 'Priorità molto alta'])]

if high_priority_areas is not None and not high_priority_areas.empty:
   print(f"\nAree ad alta priorità per interventi di edilizia residenziale: {len(high_priority_areas)} celle")
   
   # Caratteristiche demografiche
   if 'pop_tot_21' in high_priority_areas.columns:
       pop_total = high_priority_areas['pop_tot_21'].sum()
       print(f"- Popolazione coinvolta: {pop_total:.0f} abitanti")
   
   if 'densita_abitativa' in high_priority_areas.columns:
       print(f"- Densità abitativa media: {high_priority_areas['densita_abitativa'].mean():.2f} abitanti/km²")
   
   # Accesso ai servizi
   if 'indice_accessibilita_servizi' in high_priority_areas.columns:
       print(f"- Indice medio di accessibilità ai servizi: {high_priority_areas['indice_accessibilita_servizi'].mean():.4f}")
   
   # Reddito
   if 'reddito_pc' in high_priority_areas.columns:
       print(f"- Reddito pro capite medio: {high_priority_areas['reddito_pc'].mean():.2f}")
   
   # Urbanizzazione
   if 'indice_urbanizzazione' in high_priority_areas.columns:
       print(f"- Indice di urbanizzazione medio: {high_priority_areas['indice_urbanizzazione'].mean():.2f}%")

# Analisi della correlazione tra indicatori
corr_indicators = [col for col in df.columns if 'indice_' in col]
if len(corr_indicators) > 1:
   corr_matrix = df[corr_indicators].corr()
   
   print("\nMatrice di correlazione tra gli indicatori:")
   print(corr_matrix.round(2))
   
   # Identifico le correlazioni significative (>0.5 o <-0.5)
   high_corr = corr_matrix.where((corr_matrix.abs() > 0.5) & (corr_matrix.abs() < 1.0)).stack().reset_index()
   high_corr.columns = ['Indicatore 1', 'Indicatore 2', 'Correlazione']
   
   if len(high_corr) > 0:
       print("\nCorrelazioni significative tra indicatori:")
       for _, row in high_corr.iterrows():
           print(f"- {row['Indicatore 1']} e {row['Indicatore 2']}: {row['Correlazione']:.2f}")
===== CONSIDERAZIONI FINALI SUGLI INDICATORI COMPOSITI =====

Indicatori principali sviluppati:
- indice_urbanizzazione: 2285 valori validi
  Min: 0.0000, Max: 100.0000, Media: 19.9514
- indice_accessibilita: 2286 valori validi
  Min: 0.0000, Max: 155.7778, Media: 39.7416
- indice_invecchiamento: 2286 valori validi
  Min: 0.0000, Max: 500.0000, Media: 123.1560
- indice_fabbisogno_abitativo: 2286 valori validi
  Min: 0.1343, Max: 0.9466, Media: 0.5940
- indice_priorita_erp: 2286 valori validi
  Min: 0.0558, Max: 1.0898, Media: 0.7279
- indice_diversita_eta: 2286 valori validi
  Min: 0.0000, Max: 1.0000, Media: 0.7742
- indice_equilibrio_sociale: 2286 valori validi
  Min: 0.0118, Max: 0.8178, Media: 0.4562

Aree ad alta priorità per interventi di edilizia residenziale: 914 celle
- Densità abitativa media: 1050.08 abitanti/km²
- Reddito pro capite medio: 866.25
- Indice di urbanizzazione medio: 13.31%

Matrice di correlazione tra gli indicatori:
                             indice_urbanizzazione  indice_accessibilita  \
indice_urbanizzazione                         1.00                  0.57   
indice_accessibilita                          0.57                  1.00   
indice_invecchiamento                         0.23                  0.31   
indice_fabbisogno_abitativo                   0.36                  0.20   
indice_priorita_erp                          -0.01                 -0.13   
indice_diversita_eta                         -0.10                 -0.25   
indice_equilibrio_sociale                     0.56                  0.88   

                             indice_invecchiamento  \
indice_urbanizzazione                         0.23   
indice_accessibilita                          0.31   
indice_invecchiamento                         1.00   
indice_fabbisogno_abitativo                   0.03   
indice_priorita_erp                          -0.26   
indice_diversita_eta                         -0.50   
indice_equilibrio_sociale                     0.19   

                             indice_fabbisogno_abitativo  indice_priorita_erp  \
indice_urbanizzazione                               0.36                -0.01   
indice_accessibilita                                0.20                -0.13   
indice_invecchiamento                               0.03                -0.26   
indice_fabbisogno_abitativo                         1.00                 0.90   
indice_priorita_erp                                 0.90                 1.00   
indice_diversita_eta                                0.15                 0.30   
indice_equilibrio_sociale                          -0.03                -0.33   

                             indice_diversita_eta  indice_equilibrio_sociale  
indice_urbanizzazione                       -0.10                       0.56  
indice_accessibilita                        -0.25                       0.88  
indice_invecchiamento                       -0.50                       0.19  
indice_fabbisogno_abitativo                  0.15                      -0.03  
indice_priorita_erp                          0.30                      -0.33  
indice_diversita_eta                         1.00                       0.11  
indice_equilibrio_sociale                    0.11                       1.00  

Correlazioni significative tra indicatori:
- indice_urbanizzazione e indice_accessibilita: 0.57
- indice_urbanizzazione e indice_equilibrio_sociale: 0.56
- indice_accessibilita e indice_urbanizzazione: 0.57
- indice_accessibilita e indice_equilibrio_sociale: 0.88
- indice_invecchiamento e indice_diversita_eta: -0.50
- indice_fabbisogno_abitativo e indice_priorita_erp: 0.90
- indice_priorita_erp e indice_fabbisogno_abitativo: 0.90
- indice_diversita_eta e indice_invecchiamento: -0.50
- indice_equilibrio_sociale e indice_urbanizzazione: 0.56
- indice_equilibrio_sociale e indice_accessibilita: 0.88
In [51]:
# Considerazioni finali sul fabbisogno abitativo e le politiche ERS
print("\nCONSIDERAZIONI PER LE POLITICHE DI EDILIZIA RESIDENZIALE PUBBLICA E SOCIALE: per la risoluzione 8!!!!!")

print("""
Gli indicatori compositi sviluppati permettono di identificare le aree con maggiore necessità 
di interventi di edilizia residenziale pubblica e sociale, considerando fattori demografici,
socioeconomici e di accessibilità ai servizi.

L'analisi rivela relazioni significative tra urbanizzazione, accessibilità e dinamiche socio-
demografiche che influenzano le priorità per l'edilizia residenziale pubblica e sociale.

L'alta correlazione positiva (0.90) tra l'indice di fabbisogno abitativo e l'indice di priorità
ERP indica che le aree con maggiore necessità abitativa sono correttamente identificate come 
prioritarie per interventi di edilizia residenziale pubblica.

La forte correlazione (0.88) tra accessibilità e equilibrio sociale suggerisce che le aree 
meglio servite da infrastrutture e trasporti tendono ad avere una composizione sociale più 
bilanciata, confermando l'importanza dell'accessibilità per favorire l'inclusione sociale.

La correlazione negativa (-0.50) tra invecchiamento e diversità d'età indica che le aree con 
popolazione più anziana tendono ad essere meno diversificate demograficamente, evidenziando 
potenziali "enclavi generazionali".

Le 914 celle identificate come prioritarie per interventi mostrano caratteristiche interessanti: 
una densità abitativa relativamente alta (1050 abitanti/km²), un reddito pro capite basso (866.25) 
e un indice di urbanizzazione moderato (13.31%), suggerendo aree semi-periferiche con popolazione vulnerabile.

La correlazione moderata (0.57) tra urbanizzazione e accessibilità dimostra che le aree più 
urbanizzate tendono ad essere meglio servite da infrastrutture, ma questa relazione non è universale, 
indicando possibili aree urbanizzate con carenze infrastrutturali.

Questi dati potrebbero orientare politiche di edilizia residenziale che non solo aumentino 
l'offerta abitativa, ma migliorino anche l'equilibrio sociale e demografico delle aree, 
privilegiando interventi in zone con buona accessibilità ma fabbisogno abitativo elevato.
""")
CONSIDERAZIONI PER LE POLITICHE DI EDILIZIA RESIDENZIALE PUBBLICA E SOCIALE: per la risoluzione 8!!!!!

Gli indicatori compositi sviluppati permettono di identificare le aree con maggiore necessità 
di interventi di edilizia residenziale pubblica e sociale, considerando fattori demografici,
socioeconomici e di accessibilità ai servizi.

L'analisi rivela relazioni significative tra urbanizzazione, accessibilità e dinamiche socio-
demografiche che influenzano le priorità per l'edilizia residenziale pubblica e sociale.

L'alta correlazione positiva (0.90) tra l'indice di fabbisogno abitativo e l'indice di priorità
ERP indica che le aree con maggiore necessità abitativa sono correttamente identificate come 
prioritarie per interventi di edilizia residenziale pubblica.

La forte correlazione (0.88) tra accessibilità e equilibrio sociale suggerisce che le aree 
meglio servite da infrastrutture e trasporti tendono ad avere una composizione sociale più 
bilanciata, confermando l'importanza dell'accessibilità per favorire l'inclusione sociale.

La correlazione negativa (-0.50) tra invecchiamento e diversità d'età indica che le aree con 
popolazione più anziana tendono ad essere meno diversificate demograficamente, evidenziando 
potenziali "enclavi generazionali".

Le 914 celle identificate come prioritarie per interventi mostrano caratteristiche interessanti: 
una densità abitativa relativamente alta (1050 abitanti/km²), un reddito pro capite basso (866.25) 
e un indice di urbanizzazione moderato (13.31%), suggerendo aree semi-periferiche con popolazione vulnerabile.

La correlazione moderata (0.57) tra urbanizzazione e accessibilità dimostra che le aree più 
urbanizzate tendono ad essere meglio servite da infrastrutture, ma questa relazione non è universale, 
indicando possibili aree urbanizzate con carenze infrastrutturali.

Questi dati potrebbero orientare politiche di edilizia residenziale che non solo aumentino 
l'offerta abitativa, ma migliorino anche l'equilibrio sociale e demografico delle aree, 
privilegiando interventi in zone con buona accessibilità ma fabbisogno abitativo elevato.

In [52]:
# Se abbiamo dati geospaziali, creiamo una mappa delle aree ad alta priorità
gdf_with_index['classe_priorita_erp'] = df['classe_priorita_erp']

high_priority_geo = gdf_with_index[gdf_with_index['classe_priorita_erp'].isin(['Priorità alta', 'Priorità molto alta'])]

fig, ax = plt.subplots(figsize=(12, 8))
gdf_with_index.plot(color='lightgrey', ax=ax)
high_priority_geo.plot(column='indice_priorita_erp', cmap='Reds', ax=ax, legend=True)
plt.title('Aree ad alta priorità per interventi di edilizia residenziale sociale')
plt.axis('off')
plt.show()
No description has been provided for this image

Export¶

In [53]:
# Esportiamo gli indici compositi creati per usi futuri
output_file = os.path.join(os.path.expanduser("~"), "ILAB_DATA/PATRIMONIO/OUT/indici_erp.csv")

if 'indice_fabbisogno_abitativo' in df.columns or 'indice_priorita_erp' in df.columns:
    # Selezioniamo le colonne da esportare
    export_cols = [f'h3_{resolution:02}']  # ID della cella
    
    if 'indice_fabbisogno_abitativo' in df.columns:
        export_cols.append('indice_fabbisogno_abitativo')
    
    if 'indice_priorita_erp' in df.columns:
        export_cols.append('indice_priorita_erp')
    
    if 'indice_equilibrio_sociale' in df.columns:
        export_cols.append('indice_equilibrio_sociale')
    
    if 'classe_fabbisogno' in df.columns:
        export_cols.append('classe_fabbisogno')
    
    if 'classe_priorita_erp' in df.columns:
        export_cols.append('classe_priorita_erp')
    
    if 'classe_equilibrio_sociale' in df.columns:
        export_cols.append('classe_equilibrio_sociale')
    
    # Esportiamo solo se abbiamo l'ID della cella
    if f'h3_{resolution:02}' in df.columns:
        df[export_cols].to_csv(output_file, index=False)
        print(f"Indici compositi esportati in {output_file}")
    else:
        print(f"Impossibile esportare gli indici: manca l'ID della cella (h3_{resolution:02})")
Indici compositi esportati in /home/ilab/ILAB_DATA/PATRIMONIO/OUT/indici_erp.csv
In [54]:
cols_indicatori = [
    # 'indice_urbanizzazione', 
    # 'accessibilita_15min', 
    # 'accessibilita_30min',
    # 'indice_accessibilita', 
    # 'indice_invecchiamento', 
    # 'reddito_pc',
    'indice_fabbisogno_abitativo', 
    # 'classe_fabbisogno',
    'indice_priorita_erp', 
    # 'classe_priorita_erp', 
    # 'indice_diversita_eta',
    'indice_equilibrio_sociale', 
    # 'classe_equilibrio_sociale'
]
In [55]:
map_indicatori = {
    'indice_fabbisogno_abitativo': 'IFA', 
    'indice_priorita_erp': 'IPE', 
    'indice_equilibrio_sociale': 'IES', 
}
In [56]:
df_base = df.copy()

Output con classi

In [57]:
n_classes = 5

for col in cols_indicatori:
    # Calcola i natural breaks di Jenks per la classificazione
    breaks = jenks_breaks(df[col].values, n_classes=n_classes)

    # Crea una nuova colonna con le classi di Jenks
    labels = [i+1 for i in range(len(breaks)-1)]
    df.loc[:, f'{col}_'] = pd.cut(
        df[col], 
        bins=breaks, 
        labels=labels,
        include_lowest=True
    )
    df[col] = df[f'{col}_'].astype(int)
    del df[f'{col}_']

df.rename(columns=map_indicatori, inplace=True)

gdf = gpd.GeoDataFrame(df[list(map_indicatori.values()) + ['geometry', f'h3_{resolution:02}']], geometry='geometry', crs=32632)
gdf['geometry'] = gdf['geometry'].centroid.to_crs(4326)

gdf.to_file(os.path.join(out_path, f'grid_{resolution:02}_pt_tavolo1.geojson'), driver="GeoJSON")

Output con valori assoluti

In [58]:
n_classes = 5

df = df_base.copy()
df.rename(columns=map_indicatori, inplace=True)
gdf = gpd.GeoDataFrame(df[list(map_indicatori.values()) + ['geometry', f'h3_{resolution:02}']], geometry='geometry', crs=32632)
gdf['geometry'] = gdf['geometry'].centroid
cols_indicatori = map_indicatori.values()
asc3 = gpd.read_file(os.path.join(ilab_path,'ROMA','DATA','ASC_21', 'ASC_Liv_3_WGS84.shp'))
asc3 = asc3[asc3['PRO_COM']==58091].copy()
asc3_ind = asc3.sjoin(gdf)
aggs = {col:'mean' for col in cols_indicatori}
asc3_ind_g = asc3_ind.groupby('DEN_ASC3', as_index=False).agg(aggs)
for col in cols_indicatori:
    # Calcola i natural breaks di Jenks per la classificazione
    breaks = jenks_breaks(asc3_ind_g[col].values, n_classes=n_classes)

    # Crea una nuova colonna con le classi di Jenks
    labels = [i+1 for i in range(len(breaks)-1)]
    asc3_ind_g.loc[:, f'{col}_cls'] = pd.cut(
        asc3_ind_g[col], 
        bins=breaks, 
        labels=labels,
        include_lowest=True
    )
    asc3_ind_g[f'{col}_cls'] = asc3_ind_g[f'{col}_cls'].astype(int)
asc3_out = asc3.merge(asc3_ind_g, how='left', on='DEN_ASC3')
asc3_out.to_crs(4326).to_file(os.path.join(out_path, f'asc3_tavolo1.geojson'), driver="GeoJSON")
In [ ]:
 
In [ ]:
 
In [ ]:
 
In [ ]:
 
In [ ]:
 
In [ ]: