import pandas as pd #Si vous venez d'exécuter le notebook précédent, vous pouvez simplement récupérer le fichier temporaire créé. #df = pd.read_hdf("houses (1).h5") #Vous pouvez aussi récupérer une version du fichier hébergée ici: df = pd.read_csv("https://raw.githubusercontent.com/titsitits/Python_Data_Science/master/Donn%C3%A9es/houses.csv", index_col=0) df #Extract city def get_city(address): #Le nom de la rue est la partie après le dernier nombre, ou une virgule si aucun code postal n'est renseigné. On cherche donc un nombre en commençant par la fin ( range(len(address),0,-1) ) for i in range(len(address)-1,0,-1): c = address[i] if c in "0123456789,": #c est un nombre (ou une virgule), on peut sortir de la boucle break #On extrait le nom de la ville city = address[i+2:] return city my_address = "Rue de Bruxelles 42, Namur" print(get_city(my_address)) my_address = "Namur" print(get_city(my_address)) df = df.assign(city = df["address"].apply(get_city)) df = df.assign(price_per_m2 = df.price/df.surface) df = df.assign(price_per_room = df.price/df.rooms) df #Ou (idem) df["city"] = df["address"].apply(get_city) df["price_per_m2"] = df.price/df.surface df["price_per_room"] = df.price/df.rooms df df.groupby("website").mean() df.groupby("city").mean() df.corr() bxldf = df[df.city == "Bruxelles"] bxldf bxldf.corr() df.groupby("rooms").mean() df[df.rooms == 5] cat1 = "city" #cat2 = "rooms" cat2 = "website" count_analysis = df.groupby([cat1,cat2])["price"].count().unstack(fill_value=0).transpose() count_analysis price_analysis = df.groupby([cat1,cat2])["price"].mean().unstack(fill_value=0).transpose() price_analysis df #Inter-quantile range Q1 = df.price_per_room.quantile(0.25) Q3 = df.price_per_room.quantile(0.75) IQR = Q3 - Q1 h = 2 print("limits:", (Q1 - h * IQR), "to", (Q3 + h * IQR)) #Les données s'écartant fortement des quantiles sont potentiellement des anomalies (outlier en anglais) is_outlier = (df.price_per_room < (Q1 - h * IQR)) | (df.price_per_room > (Q3 + h * IQR)) df.loc[is_outlier] df2 = df[~is_outlier] #détection statistique d'outliers df2.to_csv("houses_features.csv") df2 from matplotlib import pyplot as plt plt.scatter(df.surface, df.price) plt.xlabel("Surface") plt.ylabel("Price") from matplotlib import pyplot as plt plt.bar(df.address,df.price_per_room) plt.xticks(rotation=90) #méthode intégrée de pandas df.plot.bar(y="price_per_room") plt.xticks(rotation=90) #On retire les données extrêmes df2 = df.drop([3,11]) #détection manuelle (visuelle) df2 df2.groupby("rooms").mean() result = df2.groupby("rooms").mean() #Divide each column by its sum (so that sum is 1) - so that multiple bar plots with various orders are visible result = result/result.sum() result.plot(kind="bar") #plus lisible (on transpose pour avoir un graphe par variable plutôt que par nombre de chambres) result.transpose().plot(kind="bar") website_comparison = df.groupby("website").mean() website_comparison.plot.bar(y="price") #df.plot: afficher une courbe. On trie d'abord les maisons par surface croissante pour afficher la courbe (DF.sort_values("surface")) bxldf.sort_values("surface").plot("surface","price") count_analysis.plot.pie(subplots = True, figsize = (15,15)) price_analysis.plot.bar(subplots = True, figsize = (10,10)) def detect_outliers(df, column): #Modifiez cette fonction de manière à renvoyer un dataframe contenant les outliers outliers = pd.DataFrame() return outliers #Tests out = detect_outliers(df, 'price') #Vous devriez trouver une maison à 700000€ out = detect_outliers(df, 'surface') #Vous devriez trouver une maison avec une surface de 320m² #variables catégorielles (le nombre de chambres peut être considéré comme variable catégorielle aussi) def detect_rare_cat(df, column, nmin = 2): """ Cette fonction permet de détecter des outliers dans des variables catégorielles """ outliers = pd.DataFrame() return outliers #Tests out = detect_rare_cat(df, 'city') #Vous devriez trouver une maison à Charleroi #Modifiez le code ci-dessous def is_cat(series, relative_threshold = 0.5, absolute_threshold = 20): #nombre de valeurs nvalues = len(series) #nombre de valeurs uniques ncats = len(series.unique()) #On considère la variable comme catégorielle si le nombre de valeurs uniques et plus petit qu'un seuil relatif ou absolu return False def is_num(series): #On peut considérer une variable comme numérique si elle peut être convertie en float (utiliser try/except) #series.astype(float) return False #Tests print(is_cat(df.price)) print(is_cat(df.city)) #Application sur chaque colonne is_categorical = df.apply(is_cat) is_numeric = df.apply(is_num) print(is_categorical) cols = df.columns for col in cols: print("Are there numerical outliers in %s ?" % col) print("Are there categorical outliers in %s ?" % col) # On devrait retrouver la maison de Charleroi, la maison de 320m², et la maison à 700000€ #Remarque: vous pouvez aussi commencer par extraire les noms des variables catégorielles/numériques, et puis utiliser un ecompréhension de liste dessus