import pandas as pd

# Dataset di esempio con valori mancanti e tipi eterogenei
data = {
    'Age': [25, 30, 35, None],
    'Gender': ['Male', 'Female', 'Male', 'Female'],
    'Salary': [50000, 60000, 70000, None],
    'Married': [True, False, True, None]
}

# Creazione del DataFrame a partire dal dizionario
df = pd.DataFrame(data)
print("DataFrame originale:")
print(df)

# Identificazione dei valori mancanti: matrice booleana True/False
print("\nMatrice dei valori mancanti:")
print(df.isnull())

# Conteggio dei valori mancanti per ciascuna colonna
print("\nConteggio valori mancanti per colonna:")
print(df.isnull().sum())

# Rimozione delle righe con almeno un valore mancante
df_dropped = df.dropna()
print("\nDataFrame dopo dropna():")
print(df_dropped)

# Sostituzione dei valori mancanti con strategie differenziate per colonna
# Sostituzione dei valori mancanti con valori di default
df_filled = df.copy()
df_filled['Age'] = df_filled['Age'].fillna(df_filled['Age'].mean())
df_filled['Salary'] = df_filled['Salary'].fillna(df_filled['Salary'].median())
# Conversione esplicita al tipo nullable 'boolean' prima del fillna
# per evitare il FutureWarning sul downcasting implicito di pandas
df_filled['Married'] = df_filled['Married'].astype('boolean').fillna(False)
print(df_filled)