Analisi del Questionario su Bari¶

Questo notebook analizza i dati raccolti dal questionario rivolto agli abitanti di Bari riguardo alla loro percezione della città, agli spazi di aggregazione sociale e agli eventi culturali.

Obiettivo¶

L'obiettivo di questa analisi è:

  • Estrarre i dati generali dal questionario
  • Preparare i dati per la visualizzazione in una pagina web con grafici realizzati usando la libreria d3.js
  • Organizzare le risposte in categorie per facilitare l'analisi

Struttura del Dataset¶

Il questionario contiene diverse tipologie di domande:

  • Domande demografiche: genere, età, occupazione
  • Domande a scelta multipla: sugli spazi e eventi culturali
  • Domande con scala Likert: per valutare opinioni e percezioni
  • Domande aperte: per raccogliere desideri e suggerimenti

1. Importazione delle Librerie¶

Importiamo tutte le librerie necessarie per l'analisi:

  • pandas: per manipolare i dati in formato tabellare
  • json: per esportare i dati in formato JSON
  • numpyencoder: per gestire tipi di dati numpy nell'esportazione JSON
  • re: per le espressioni regolari (elaborazione testo)
  • Counter: per contare le occorrenze negli elementi
In [1]:
import pandas as pd
import json
from numpyencoder import NumpyEncoder
import re
from collections import Counter

2. Caricamento dei Dati¶

Carichiamo il file Excel contenente le risposte anonime al questionario. Il parametro index_col=False indica che non vogliamo usare nessuna colonna come indice.

In [2]:
# Carica il file Excel con le risposte del questionario
df = pd.read_excel("questionario anonimo.xlsx", index_col=False)

3. Esplorazione delle Colonne¶

Visualizziamo i nomi delle colonne per capire quali domande sono state poste nel questionario.

In [3]:
# Mostra tutte le colonne (domande) del questionario
df.columns
Out[3]:
Index(['Di che genere sei?', 'Quanti anni hai?', 'Qual è la tua occupazione?',
       'Che rapporto hai con la città di Bari?',
       'Per te partecipare a incontri di aggregazione sociale, eventi culturali e dibattiti politici è: ',
       'A cosa è dovuta, se c’è, la tua difficoltà nella partecipazione?',
       'Bari offre spazi di aggregazione sociale e culturale? ',
       'Ritieni che Bari sia una città a misura di persone Under 30? ',
       'Quale spazio sogni a Bari?', 'Frequenti questi spazi? ', 'Quali?',
       'Quanto ti senti accoltə negli spazi che frequenti?',
       'Ritieni che questi spazi conoscano e siano attenti ai bisogni della comunità che li frequentano?',
       'Come giudichi il dialogo tra questi spazi?',
       'Partecipi a eventi culturali a Bari?',
       'A che tipo di eventi partecipi?',
       'Secondo te che tipo di eventi culturali mancano in città e quali tra questi vorresti a Bari?',
       'Condividi l’intento e le finalità delle recenti ordinanze per «contrastare gli effetti negativi della movida»?',
       'Come pensi che vadano gestiti questi fenomeni? ',
       'Hai mai sentito parlare di Scomodo?',
       'Se sì, ti piacerebbe una Redazione di Scomodo a Bari?',
       'Se avessi un desiderio per Bari, quale sarebbe? ',
       'Come incide sul tuo benessere il rapporto che hai con la città di Bari? ',
       'Sei a Bari, sei felice?', '@dropdown'],
      dtype='object')

4. Categorizzazione delle Domande¶

Organizziamo le domande in base al tipo di analisi che vogliamo fare:

Domande per Grafici a Distribuzione¶

Queste sono domande con risposte categoriche che vogliamo visualizzare come grafici a barre o torta:

  • Dati demografici (genere, età, occupazione)
  • Rapporto con Bari
  • Conoscenza di Scomodo
  • Interesse per Scomodo a Bari
  • Sei a Bari Sei Felice

Domande con Scala Likert¶

Queste domande usano scale di valutazione (es. 1-5, molto importante/poco importante):

  • Importanza della partecipazione sociale
  • Valutazione degli spazi esistenti
  • Sentirsi accolti negli spazi
  • Attenzione ai bisogni della comunità
  • Dialogo tra spazi
  • Partecipazione agli eventi
  • Impatto sul benessere

Domande a Scelta Multipla¶

Queste permettono più risposte per la stessa domanda:

  • Difficoltà nella partecipazione
  • Tipi di eventi frequentati
  • Gestione dei fenomeni della movida
In [4]:
# Indici delle colonne per grafici a distribuzione (risposte singole)
plotDist = [
    0,   # Di che genere sei?
    1,   # Quanti anni hai?
    2,   # Qual è la tua occupazione?
    3,   # Che rapporto hai con la città di Bari?
    19,  # Hai mai sentito parlare di Scomodo?
    20,  # Se sì, ti piacerebbe una Redazione di Scomodo a Bari?
    23   # Sei a Bari, sei felice?
]

# Indici delle colonne con scale Likert (valutazioni su scala)
# Nota: i valori per queste scale non sono ancora definiti, 
# quindi vengono raggruppate separatamente
likert = [
    4,   # Per te partecipare a incontri di aggregazione sociale...
    6,   # Bari offre spazi di aggregazione sociale e culturale?
    7,   # Ritieni che Bari sia una città a misura di persone Under 30?
    11,  # Quanto ti senti accoltə negli spazi che frequenti?
    12,  # Ritieni che questi spazi conoscano e siano attenti ai bisogni...
    13,  # Come giudichi il dialogo tra questi spazi?
    14,  # Partecipi a eventi culturali a Bari?
    22   # Come incide sul tuo benessere il rapporto che hai con la città di Bari?
]

# Indici delle colonne con risposte multiple (da processare diversamente)
toHotEncode = [
    5,   # A cosa è dovuta, se c'è, la tua difficoltà nella partecipazione?
    15,  # A che tipo di eventi partecipi?
    18   # Come pensi che vadano gestiti questi fenomeni?
]

5. Elaborazione dei Dati per la Visualizzazione¶

Creiamo un dizionario che conterrà tutti i dati processati per i grafici. Per ogni domanda, contiamo quante volte appare ogni risposta possibile.

In [5]:
# Dizionario principale che conterrà tutti i dati per i grafici
toPlot = {}

# Processa le domande con distribuzione semplice
# Per ogni domanda, conta quante volte appare ogni risposta
for colIdx in plotDist:
    colName = df.columns[colIdx]  # Nome della domanda
    # value_counts() conta automaticamente le occorrenze di ogni valore
    toPlot[colName] = dict(df[colName].value_counts())

# Crea una sezione separata per le domande Likert
# Queste vengono raggruppate perché potrebbero aver bisogno di elaborazione speciale
toPlot["likert"] = {}
for colIdx in likert:
    colName = df.columns[colIdx]
    toPlot["likert"][colName] = dict(df[colName].value_counts())

6. Elaborazione delle Domande a Scelta Multipla¶

Alcune domande permettono risposte multiple, che nel dataset sono salvate come stringhe separate da virgole. Dobbiamo "spacchettare" queste risposte e contare ogni opzione singolarmente.

In [6]:
def fromOneHotToCount(col_name):
    """
    Funzione che elabora le colonne con risposte multiple.
    
    Come funziona:
    1. Prende una colonna con risposte del tipo "Opzione A, Opzione B, Opzione C"
    2. Separa ogni risposta usando la virgola come separatore
    3. Conta quante volte appare ogni singola opzione
    
    Parametri:
    col_name: nome della colonna da processare
    
    Ritorna:
    Un dizionario con opzione -> numero di volte che è stata scelta
    """
    # Counter è uno strumento che conta automaticamente le occorrenze
    counter = Counter()

    # Esamina ogni risposta nella colonna
    for val in df[col_name]:
        # Controlla se la risposta è una stringa (non vuota o NaN)
        if isinstance(val, str):
            # Separa le risposte multiple usando una regex specializzata
            # Il pattern ', (?=[A-Z])' separa alla virgola solo se seguita da maiuscola
            # Questo evita di separare erroneamente nei nomi composti
            items = re.split(r', (?=[A-Z])', val)
            # Aggiunge ogni elemento separato al contatore
            counter.update(items)

    # Converte il Counter in un dizionario normale
    return dict(counter)

Applicazione della Funzione alle Domande Multiple¶

In [7]:
# Applica la funzione di elaborazione a tutte le domande a scelta multipla
for colIdx in toHotEncode:
    colName = df.columns[colIdx]
    # Usa la funzione personalizzata per contare le risposte multiple
    toPlot[colName] = fromOneHotToCount(colName)

7. Esportazione dei Dati per la Visualizzazione Web¶

Salviamo tutti i dati elaborati in un file JSON che potrà essere utilizzato dalla pagina web con i grafici D3.

Parametri del salvataggio:

  • indent=4: formatta il JSON in modo leggibile
  • cls=NumpyEncoder: gestisce eventuali tipi di dati numpy
  • ensure_ascii=False: mantiene i caratteri speciali italiani (à, è, ì, ecc.)
In [8]:
# Esporta tutti i dati elaborati in formato JSON
with open ("toPlot.json", "w", encoding="utf-8") as f:
    json.dump(toPlot, f, indent=4, cls=NumpyEncoder, ensure_ascii=False)

8. Esportazioni Specializzate¶

Creiamo alcuni file separati per analisi specifiche su temi particolari.

8.1 Analisi degli Spazi di Aggregazione¶

Esportiamo le domande relative agli spazi che i giovani frequentano a Bari:

  • Quale spazio sognano
  • Se frequentano spazi esistenti
  • Quali spazi frequentano
  • Quanto si sentono accolti
In [9]:
# Esporta le colonne relative agli spazi di aggregazione
# Colonne: "Quale spazio sogni a Bari?", "Frequenti questi spazi?", 
#          "Quali?", "Quanto ti senti accoltə negli spazi che frequenti?"
df[[df.columns[8], df.columns[9], df.columns[10], df.columns[11]]].to_excel("spazi.xlsx", index=False)

8.2 Analisi degli Eventi Culturali¶

Esportiamo le domande relative agli eventi culturali a Bari:

  • Che tipo di eventi culturali mancano
  • Opinioni sulle ordinanze della movida
  • Come gestire i fenomeni correlati
In [10]:
# Esporta le colonne relative agli eventi culturali
# Colonne: "Secondo te che tipo di eventi culturali mancano...", 
#          "Condividi l'intento... delle ordinanze...", "Come pensi che vadano gestiti..."
df[[df.columns[16], df.columns[17], df.columns[18]]].to_excel("eventi.xlsx", index=False)

8.3 Raccolta dei Sogni e Desideri¶

Esportiamo tutte le risposte alla domanda aperta "Se avessi un desiderio per Bari, quale sarebbe?" in un file di testo per facilitare l'analisi qualitativa.

Nota: Usiamo dropna() per rimuovere le risposte vuote e unique() per evitare duplicati.

In [11]:
# Esporta tutti i desideri unici per Bari in un file di testo
with open ("sogni.txt", "w", encoding="utf-8") as f:
    # Prende la colonna 21 ("Se avessi un desiderio per Bari, quale sarebbe?"),
    # rimuove i valori vuoti e duplicati, poi scrive ogni risposta su una riga
    for line in list(df[df.columns[21]].dropna().unique()):
        f.write(line + "\n")

Conclusione¶

Questo notebook ha elaborato i dati del questionario su Bari producendo:

File di Output:¶

  1. toPlot.json: Contiene tutti i dati numerici per i grafici della pagina web
  2. spazi.xlsx: Analisi specifica sugli spazi di aggregazione
  3. eventi.xlsx: Analisi specifica sugli eventi culturali
  4. sogni.txt: Raccolta di tutti i desideri espressi per la città

Struttura dei Dati JSON:¶

  • Categorie principali: dati demografici e preferenze generali
  • Sezione Likert: valutazioni su scala (da elaborare successivamente)
  • Domande multiple: ogni opzione contata singolarmente

I dati sono ora pronti per essere utilizzati nella visualizzazione web con D3.js.