Refactor code structure for improved readability and maintainability

This commit is contained in:
2026-02-17 17:53:50 +01:00
parent ede97b228b
commit 9f602bc6b8
9 changed files with 2430 additions and 1125 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 MiB

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,883 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "41865f50",
"metadata": {},
"source": [
"# Modélisation du Risque Venteux : La Tempête Martin (1999)\n",
"\n",
"### Date : 17 février 2026 \n",
"### Module : Enjeux et modélisation des risques climatiques\n",
"\n",
"## Auteur : Arthur DANJOU - M2 ISF"
]
},
{
"cell_type": "code",
"execution_count": 98,
"id": "3e0443b0",
"metadata": {},
"outputs": [],
"source": [
"import geopandas as gpd\n",
"import rasterio\n",
"\n",
"import numpy as np\n",
"import pandas as pd\n"
]
},
{
"cell_type": "code",
"execution_count": 99,
"id": "0276c2ab",
"metadata": {},
"outputs": [],
"source": [
"src_path = \"./data/TempeteMartinWGS84.tif\"\n",
"communes_path = \"./data/communes.gpkg\"\n",
"batiments_path = \"./data/batiments.gpkg\"\n"
]
},
{
"cell_type": "markdown",
"id": "97455182",
"metadata": {},
"source": [
"## Partie 1 : Analyse de l'aléa et des données d'exposition"
]
},
{
"cell_type": "markdown",
"id": "aeacf057",
"metadata": {},
"source": [
"### 1.1. Chargement et exploration"
]
},
{
"cell_type": "code",
"execution_count": 100,
"id": "f08146d4",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CRS Raster: EPSG:4326\n",
"CRS Communes: EPSG:2154\n",
"CRS Bâtiments: EPSG:2154\n",
"\n",
"Extrait Table Communes:\n",
" POPULATION SUPERF_CAD DATE_APP DATE_CONF \\\n",
"count 630.000000 630.000000 45 9 \n",
"mean 1348.401587 1616.952381 1992-11-13 14:56:00 2020-03-22 10:40:00 \n",
"min 43.000000 120.000000 1970-12-01 00:00:00 2019-01-01 00:00:00 \n",
"25% 316.500000 880.000000 1973-01-01 00:00:00 2019-01-01 00:00:00 \n",
"50% 646.500000 1385.000000 1979-06-01 00:00:00 2019-01-01 00:00:00 \n",
"75% 1320.500000 2030.000000 2016-01-01 00:00:00 2019-01-01 00:00:00 \n",
"max 79961.000000 8940.000000 2025-01-01 00:00:00 2025-01-01 00:00:00 \n",
"std 3787.117325 1086.952500 NaN NaN \n",
"\n",
" DATE_RCT \n",
"count 630 \n",
"mean 2022-01-01 00:00:00 \n",
"min 2022-01-01 00:00:00 \n",
"25% 2022-01-01 00:00:00 \n",
"50% 2022-01-01 00:00:00 \n",
"75% 2022-01-01 00:00:00 \n",
"max 2022-01-01 00:00:00 \n",
"std NaN \n",
"\n",
"Extrait Table Bâtiments:\n",
" NB_ETAGES HAUTEUR Z_MIN_SOL Z_MAX_TOIT\n",
"count 45989.000000 99954.000000 100552.000000 87034.000000\n",
"mean 1.308965 4.129201 26.883678 33.297492\n",
"std 0.560797 1.827434 25.609158 26.130012\n",
"min 0.000000 0.000000 -3.000000 0.000000\n",
"25% 1.000000 3.000000 7.800000 13.800000\n",
"50% 1.000000 3.800000 18.000000 24.500000\n",
"75% 2.000000 4.900000 38.000000 44.900000\n",
"max 14.000000 50.400000 158.300000 165.900000\n"
]
}
],
"source": [
"src = rasterio.open(src_path)\n",
"communes = gpd.read_file(communes_path)\n",
"batiments = gpd.read_file(batiments_path)\n",
"\n",
"print(f\"CRS Raster: {src.crs}\")\n",
"print(f\"CRS Communes: {communes.crs}\")\n",
"print(f\"CRS Bâtiments: {batiments.crs}\")\n",
"\n",
"print(\"\\nExtrait Table Communes:\")\n",
"print(communes.describe())\n",
"print(\"\\nExtrait Table Bâtiments:\")\n",
"print(batiments.describe())\n"
]
},
{
"cell_type": "markdown",
"id": "4bf50c0c",
"metadata": {},
"source": [
"### 1.2. Cartographie de la zone d'étude\n",
"\n",
"![Carte de la zone d'étude](./carte%201.png)"
]
},
{
"cell_type": "markdown",
"id": "839a382f",
"metadata": {},
"source": [
"### 1.3. Statistiques de l'aléa"
]
},
{
"cell_type": "code",
"execution_count": 101,
"id": "c17eee41",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Statistiques descriptives de l'aléa (Martin 1999) :\n",
" min max mean std\n",
"Valeurs 11.906469 52.240498 19.885484 6.9541\n"
]
}
],
"source": [
"from rasterstats import zonal_stats\n",
"from shapely.geometry import box\n",
"\n",
"bbox = box(*src.bounds)\n",
"bbox_gdf = gpd.GeoDataFrame({\"geometry\": [bbox]}, crs=src.crs)\n",
"\n",
"global_stats = zonal_stats(\n",
" bbox_gdf, \"./data/TempeteMartinWGS84.tif\", stats=[\"min\", \"max\", \"mean\", \"std\"],\n",
")[0]\n",
"\n",
"df_stats = pd.DataFrame([global_stats], index=[\"Valeurs\"])\n",
"print(\"Statistiques descriptives de l'aléa (Martin 1999) :\")\n",
"print(df_stats)\n"
]
},
{
"cell_type": "markdown",
"id": "30c264be",
"metadata": {},
"source": [
"## Partie 2 : Croisement Aléa-Territoire et Analyse de l'Exposition"
]
},
{
"cell_type": "markdown",
"id": "58378855",
"metadata": {},
"source": [
"### 2.1. Statistiques zonales par commune"
]
},
{
"cell_type": "code",
"execution_count": 102,
"id": "a43f2671",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" vitesse_moyenne vitesse_maximale vitesse_minimale vitesse_ecart_type\n",
"count 630.000000 630.000000 630.000000 630.000000\n",
"mean 44.006877 44.429421 43.591589 0.244895\n",
"std 3.106150 3.153961 3.088576 0.197454\n",
"min 37.909477 38.180199 37.507687 0.010203\n",
"25% 41.646152 41.868794 41.482575 0.134389\n",
"50% 43.455757 43.896006 43.031494 0.199136\n",
"75% 46.056098 46.597459 45.413697 0.299832\n",
"max 51.705040 52.240498 51.531330 2.019503\n",
" INSEE_COM NOM vitesse_moyenne vitesse_maximale \\\n",
"0 17058 Bourcefranc-le-Chapus 50.242519 50.528202 \n",
"1 16330 Saint-Laurent-de-Cognac 43.382690 43.635235 \n",
"2 16193 Louzac-Saint-André 43.396835 43.661594 \n",
"3 85049 Champagné-les-Marais 43.576344 45.888340 \n",
"4 17105 Chives 41.404770 41.532009 \n",
"\n",
" vitesse_minimale vitesse_ecart_type \n",
"0 50.052124 0.136840 \n",
"1 43.150967 0.149604 \n",
"2 43.078400 0.174605 \n",
"3 41.591129 1.181755 \n",
"4 41.293308 0.063048 \n"
]
}
],
"source": [
"from rasterio.mask import mask\n",
"\n",
"if communes.crs != src.crs:\n",
" communes = communes.to_crs(src.crs)\n",
"\n",
"resultats_stats = []\n",
"nodata_val = src.nodata\n",
"\n",
"for _, row in communes.iterrows():\n",
" try:\n",
" out_image, _ = mask(src, [row.geometry], crop=True, all_touched=True)\n",
" data = out_image[0]\n",
"\n",
" values = data[(data != nodata_val) & (np.isfinite(data))]\n",
"\n",
" if values.size > 0:\n",
" resultats_stats.append(\n",
" {\n",
" \"INSEE_COM\": row[\"INSEE_COM\"],\n",
" \"NOM\": row[\"NOM\"],\n",
" \"vitesse_moyenne\": float(np.mean(values)),\n",
" \"vitesse_maximale\": float(np.max(values)),\n",
" \"vitesse_minimale\": float(np.min(values)),\n",
" \"vitesse_ecart_type\": float(np.std(values)),\n",
" },\n",
" )\n",
" except (ValueError, RuntimeError):\n",
" continue\n",
"\n",
"communes_resultats = pd.DataFrame(resultats_stats)\n",
"print(communes_resultats.describe())\n",
"print(communes_resultats.head())\n"
]
},
{
"cell_type": "markdown",
"id": "56c4809f",
"metadata": {},
"source": [
"### 2.2. Identification des communes les plus exposées"
]
},
{
"cell_type": "code",
"execution_count": 103,
"id": "66646fe2",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Top 3 des communes - Vitesse de vent moyenne la plus élevée :\n",
" NOM vitesse_moyenne\n",
"16 La Brée-les-Bains 51.705040\n",
"349 Saint-Georges-d'Oléron 51.696590\n",
"583 Saint-Pierre-d'Oléron 51.500526\n",
"\n",
"Top 3 des communes - Vitesse de vent maximale la plus élevée :\n",
" NOM vitesse_maximale\n",
"349 Saint-Georges-d'Oléron 52.240498\n",
"583 Saint-Pierre-d'Oléron 52.078884\n",
"459 Île-d'Aix 51.875992\n"
]
}
],
"source": [
"top_3_moyenne = communes_resultats.nlargest(3, \"vitesse_moyenne\")[\n",
" [\"NOM\", \"vitesse_moyenne\"]\n",
"]\n",
"top_3_maximale = communes_resultats.nlargest(3, \"vitesse_maximale\")[\n",
" [\"NOM\", \"vitesse_maximale\"]\n",
"]\n",
"\n",
"print(\"Top 3 des communes - Vitesse de vent moyenne la plus élevée :\")\n",
"print(top_3_moyenne)\n",
"\n",
"print(\"\\nTop 3 des communes - Vitesse de vent maximale la plus élevée :\")\n",
"print(top_3_maximale)\n"
]
},
{
"cell_type": "markdown",
"id": "e11914f1",
"metadata": {},
"source": [
"### 2.3. Exposition des bâtiments"
]
},
{
"cell_type": "markdown",
"id": "7a86da2f",
"metadata": {},
"source": [
"#### 2.3.1. Transformation de la couche de polygones `batiments.gpkg` en une couche de points (centroïdes)."
]
},
{
"cell_type": "code",
"execution_count": 104,
"id": "da43bffb",
"metadata": {},
"outputs": [],
"source": [
"batiments_pts = batiments.copy()\n",
"batiments_pts[\"geometry\"] = batiments_pts.geometry.centroid\n"
]
},
{
"cell_type": "markdown",
"id": "d24327f6",
"metadata": {},
"source": [
"#### 2.3.2. Pour chaque bâtiment (point), extraction de la valeur de vitesse de vent correspondante depuis le raster `TempeteMartinWGS84.tif`."
]
},
{
"cell_type": "code",
"execution_count": 105,
"id": "dcf3d4d6",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Nombre de bâtiments avec une valeur de vent valide : 101370\n",
" ID USAGE1 NB_ETAGES MAT_TOITS \\\n",
"0 BATIMENT0000000258101741 Résidentiel 1.0 10 \n",
"1 BATIMENT0000000292067994 Indifférencié NaN None \n",
"2 BATIMENT0000000292068000 Commercial et services 2.0 None \n",
"3 BATIMENT0000000292068017 Indifférencié NaN None \n",
"4 BATIMENT0000000292068024 Indifférencié NaN None \n",
"\n",
" HAUTEUR Z_MIN_SOL Z_MAX_TOIT geometry vitesse_vent \n",
"0 3.3 50.0 53.7 POINT (-0.50422 46.09339) 41.530777 \n",
"1 5.3 5.0 NaN POINT (-1.17684 46.0137) 51.538124 \n",
"2 6.1 6.5 14.6 POINT (-1.17687 46.01255) 51.538124 \n",
"3 2.7 6.0 9.3 POINT (-1.17691 46.012) 51.538124 \n",
"4 3.4 6.0 11.5 POINT (-1.17672 46.01214) 51.538124 \n",
" NB_ETAGES HAUTEUR Z_MIN_SOL Z_MAX_TOIT vitesse_vent\n",
"count 45989.000000 99954.000000 100552.000000 87034.000000 101370.000000\n",
"mean 1.308965 4.129201 26.883678 33.297492 46.290665\n",
"std 0.560797 1.827434 25.609158 26.130012 3.521599\n",
"min 0.000000 0.000000 -3.000000 0.000000 37.835918\n",
"25% 1.000000 3.000000 7.800000 13.800000 43.306957\n",
"50% 1.000000 3.800000 18.000000 24.500000 46.618694\n",
"75% 2.000000 4.900000 38.000000 44.900000 49.390682\n",
"max 14.000000 50.400000 158.300000 165.900000 52.240498\n"
]
}
],
"source": [
"batiments_pts = batiments.copy()\n",
"batiments_pts[\"geometry\"] = batiments_pts.geometry.centroid\n",
"\n",
"if batiments_pts.crs != src.crs:\n",
" batiments_pts = batiments_pts.to_crs(src.crs)\n",
"\n",
"coords = [(geom.x, geom.y) for geom in batiments_pts.geometry]\n",
"\n",
"sampled = list(src.sample(coords))\n",
"batiments_pts[\"vitesse_vent\"] = [val[0] for val in sampled]\n",
"\n",
"batiments_pts[\"vitesse_vent\"] = batiments_pts[\"vitesse_vent\"].replace(\n",
" src.nodata, np.nan,\n",
")\n",
"\n",
"print(\n",
" f\"Nombre de bâtiments avec une valeur de vent valide : {batiments_pts['vitesse_vent'].notna().sum()}\",\n",
")\n",
"print(batiments_pts.head())\n",
"print(batiments_pts.describe())\n"
]
},
{
"cell_type": "markdown",
"id": "0f276ac1",
"metadata": {},
"source": [
"## Partie 3 : Estimation des Pertes Économiques"
]
},
{
"cell_type": "markdown",
"id": "2571b7c8",
"metadata": {},
"source": [
"### 3.1. Calcul de la valeur assurée\n"
]
},
{
"cell_type": "code",
"execution_count": 113,
"id": "34176db8",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Aperçu du calcul de la valeur assurée :\n",
" surface valeur_assuree\n",
"0 184.095 276142.499996\n",
"1 12.905 19357.499999\n",
"2 617.905 926857.500003\n",
"3 12.575 18862.500000\n",
"4 98.280 147420.000003\n",
" NB_ETAGES HAUTEUR Z_MIN_SOL Z_MAX_TOIT vitesse_vent \\\n",
"count 45989.000000 99954.000000 100552.000000 87034.000000 101370.000000 \n",
"mean 1.308965 4.129201 26.883678 33.297492 46.290665 \n",
"std 0.560797 1.827434 25.609158 26.130012 3.521599 \n",
"min 0.000000 0.000000 -3.000000 0.000000 37.835918 \n",
"25% 1.000000 3.000000 7.800000 13.800000 43.306957 \n",
"50% 1.000000 3.800000 18.000000 24.500000 46.618694 \n",
"75% 2.000000 4.900000 38.000000 44.900000 49.390682 \n",
"max 14.000000 50.400000 158.300000 165.900000 52.240498 \n",
"\n",
" surface valeur_assuree dr perte_economique \\\n",
"count 101508.000000 1.015080e+05 101508.000000 1.015080e+05 \n",
"mean 110.040776 1.650612e+05 0.723555 1.162034e+05 \n",
"std 266.385398 3.995781e+05 0.176776 2.899683e+05 \n",
"min 0.270000 4.050000e+02 0.300000 2.970000e+02 \n",
"25% 21.120000 3.168000e+04 0.550000 2.241750e+04 \n",
"50% 68.175000 1.022625e+05 0.800000 6.892875e+04 \n",
"75% 137.566250 2.063494e+05 0.800000 1.479420e+05 \n",
"max 28990.995000 4.348649e+07 1.000000 2.883041e+07 \n",
"\n",
" vulnerability_factor perte_affinee variation_perte \\\n",
"count 101508.000000 1.015080e+05 101508.000000 \n",
"mean 1.054569 1.247277e+05 8524.304851 \n",
"std 0.107021 2.931109e+05 18083.123625 \n",
"min 0.800000 2.970000e+02 -204846.000000 \n",
"25% 1.000000 2.226122e+04 0.000000 \n",
"50% 1.000000 7.239960e+04 0.000000 \n",
"75% 1.200000 1.646645e+05 16586.475000 \n",
"max 1.200000 2.883041e+07 379797.600009 \n",
"\n",
" vitesse_vent_stress dr_stress \n",
"count 101370.000000 101508.000000 \n",
"mean 50.919731 0.897744 \n",
"std 3.873759 0.129135 \n",
"min 41.619511 0.550000 \n",
"25% 47.637653 0.800000 \n",
"50% 51.280563 1.000000 \n",
"75% 54.329750 1.000000 \n",
"max 57.464550 1.000000 \n",
"\n",
"Valeur totale du portefeuille assuré : 16,755,028,665.00 €\n"
]
}
],
"source": [
"cout_reconstruction_m2 = 1500\n",
"\n",
"batiments[\"surface\"] = batiments.geometry.area\n",
"batiments_pts[\"surface\"] = batiments.geometry.area\n",
"batiments_pts[\"valeur_assuree\"] = batiments_pts[\"surface\"] * cout_reconstruction_m2\n",
"\n",
"print(\"Aperçu du calcul de la valeur assurée :\")\n",
"print(batiments_pts[[\"surface\", \"valeur_assuree\"]].head())\n",
"\n",
"print(batiments_pts.describe())\n",
"\n",
"print(\n",
" f\"\\nValeur totale du portefeuille assuré : {batiments_pts['valeur_assuree'].sum():,.2f} €\",\n",
")\n"
]
},
{
"cell_type": "markdown",
"id": "a9c14079",
"metadata": {},
"source": [
"### 3.2. Application de la fonction de dommage"
]
},
{
"cell_type": "code",
"execution_count": 114,
"id": "6c6bcd00",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" NB_ETAGES HAUTEUR Z_MIN_SOL Z_MAX_TOIT vitesse_vent \\\n",
"count 45989.000000 99954.000000 100552.000000 87034.000000 101370.000000 \n",
"mean 1.308965 4.129201 26.883678 33.297492 46.290665 \n",
"std 0.560797 1.827434 25.609158 26.130012 3.521599 \n",
"min 0.000000 0.000000 -3.000000 0.000000 37.835918 \n",
"25% 1.000000 3.000000 7.800000 13.800000 43.306957 \n",
"50% 1.000000 3.800000 18.000000 24.500000 46.618694 \n",
"75% 2.000000 4.900000 38.000000 44.900000 49.390682 \n",
"max 14.000000 50.400000 158.300000 165.900000 52.240498 \n",
"\n",
" surface valeur_assuree dr perte_economique \\\n",
"count 101508.000000 1.015080e+05 101508.000000 1.015080e+05 \n",
"mean 110.040776 1.650612e+05 0.723555 1.162034e+05 \n",
"std 266.385398 3.995781e+05 0.176776 2.899683e+05 \n",
"min 0.270000 4.050000e+02 0.300000 2.970000e+02 \n",
"25% 21.120000 3.168000e+04 0.550000 2.241750e+04 \n",
"50% 68.175000 1.022625e+05 0.800000 6.892875e+04 \n",
"75% 137.566250 2.063494e+05 0.800000 1.479420e+05 \n",
"max 28990.995000 4.348649e+07 1.000000 2.883041e+07 \n",
"\n",
" vulnerability_factor perte_affinee variation_perte \\\n",
"count 101508.000000 1.015080e+05 101508.000000 \n",
"mean 1.054569 1.247277e+05 8524.304851 \n",
"std 0.107021 2.931109e+05 18083.123625 \n",
"min 0.800000 2.970000e+02 -204846.000000 \n",
"25% 1.000000 2.226122e+04 0.000000 \n",
"50% 1.000000 7.239960e+04 0.000000 \n",
"75% 1.200000 1.646645e+05 16586.475000 \n",
"max 1.200000 2.883041e+07 379797.600009 \n",
"\n",
" vitesse_vent_stress dr_stress \n",
"count 101370.000000 101508.000000 \n",
"mean 50.919731 0.897744 \n",
"std 3.873759 0.129135 \n",
"min 41.619511 0.550000 \n",
"25% 47.637653 0.800000 \n",
"50% 51.280563 1.000000 \n",
"75% 54.329750 1.000000 \n",
"max 57.464550 1.000000 \n",
"count 1.015080e+05\n",
"mean 1.162034e+05\n",
"std 2.899683e+05\n",
"min 2.970000e+02\n",
"25% 2.241750e+04\n",
"50% 6.892875e+04\n",
"75% 1.479420e+05\n",
"max 2.883041e+07\n",
"Name: perte_economique, dtype: float64\n"
]
}
],
"source": [
"def get_damage_ratio(vitesse: float) -> float:\n",
" \"\"\"Compute the damage ratio based on wind speed.\"\"\"\n",
" if vitesse < 25:\n",
" return 0.00\n",
" if 25 <= vitesse < 30:\n",
" return 0.05\n",
" if 30 <= vitesse < 35:\n",
" return 0.15\n",
" if 35 <= vitesse < 40:\n",
" return 0.30\n",
" if 40 <= vitesse < 45:\n",
" return 0.55\n",
" if 45 <= vitesse < 50:\n",
" return 0.80\n",
" return 1.00\n",
"\n",
"\n",
"batiments_pts[\"dr\"] = batiments_pts[\"vitesse_vent\"].apply(get_damage_ratio)\n",
"batiments_pts[\"perte_economique\"] = (\n",
" batiments_pts[\"valeur_assuree\"] * batiments_pts[\"dr\"]\n",
")\n",
"\n",
"print(batiments_pts.describe())\n",
"print(batiments_pts[\"perte_economique\"].describe())\n"
]
},
{
"cell_type": "markdown",
"id": "ce8318ab",
"metadata": {},
"source": [
"### 3.3. Analyse des pertes totales"
]
},
{
"cell_type": "code",
"execution_count": 108,
"id": "ed34bee8",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Perte économique totale : 11,795,577,774.00 €\n",
"Nombre total de bâtiments endommagés : 101508\n",
"Perte moyenne par bâtiment endommagé : 116,203.43 €\n"
]
}
],
"source": [
"perte_totale = batiments_pts[\"perte_economique\"].sum()\n",
"batiments_endommages = batiments_pts[batiments_pts[\"perte_economique\"] > 0]\n",
"nb_endommages = len(batiments_endommages)\n",
"perte_moyenne = perte_totale / nb_endommages if nb_endommages > 0 else 0\n",
"\n",
"print(f\"Perte économique totale : {perte_totale:,.2f} €\")\n",
"print(f\"Nombre total de bâtiments endommagés : {nb_endommages}\")\n",
"print(f\"Perte moyenne par bâtiment endommagé : {perte_moyenne:,.2f} €\")\n"
]
},
{
"cell_type": "code",
"execution_count": 109,
"id": "33f1fffc",
"metadata": {},
"outputs": [],
"source": [
"batiments_with_commune = gpd.sjoin(\n",
" batiments_pts,\n",
" communes[[\"INSEE_COM\", \"NOM\", \"geometry\"]],\n",
" how=\"left\",\n",
" predicate=\"within\",\n",
")\n",
"\n",
"pertes_communes = (\n",
" batiments_with_commune.groupby(\"INSEE_COM\")[\"perte_economique\"].sum().reset_index()\n",
")\n",
"\n",
"communes_final = communes.merge(pertes_communes, on=\"INSEE_COM\", how=\"left\")\n",
"communes_final[\"perte_economique\"] = communes_final[\"perte_economique\"].fillna(0)\n",
"\n",
"communes_final.to_file(\n",
" \"./data/communes_pertes_final.gpkg\", layer=\"pertes_par_commune\", driver=\"GPKG\",\n",
")\n"
]
},
{
"cell_type": "markdown",
"id": "b0084a6a",
"metadata": {},
"source": [
"![Carte de la zone d'étude](./carte%202.png)"
]
},
{
"cell_type": "markdown",
"id": "58d9c827",
"metadata": {},
"source": [
"## Partie 4 : Analyse Exploratoire et Approfondissement"
]
},
{
"cell_type": "markdown",
"id": "936fb1ee",
"metadata": {},
"source": [
"### Piste 1 : Modulation de la fonction de dommage par le matériau"
]
},
{
"cell_type": "code",
"execution_count": 116,
"id": "7170836a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" nb_batiments perte_economique perte_affinee variation_perte\n",
"MAT_TOITS \n",
"10 32159 4.726775e+09 5.672130e+09 9.453550e+08\n",
"01 4424 3.979362e+08 3.183490e+08 -7.958724e+07\n",
"00 2851 2.812398e+08 2.812398e+08 0.000000e+00\n",
"13 575 8.918949e+07 8.027054e+07 -8.918949e+06\n",
"90 633 7.244555e+07 7.244555e+07 0.000000e+00\n",
"40 213 4.847359e+07 4.362623e+07 -4.847359e+06\n",
"19 240 3.508498e+07 3.508498e+07 0.000000e+00\n",
"09 567 3.065386e+07 3.371924e+07 3.065386e+06\n",
"20 224 2.967865e+07 2.374292e+07 -5.935731e+06\n",
"12 90 1.518114e+07 1.669925e+07 1.518114e+06\n",
"30 93 1.484553e+07 1.336098e+07 -1.484553e+06\n",
"14 74 1.074817e+07 9.673353e+06 -1.074817e+06\n",
"49 7 4.121464e+06 4.121464e+06 0.000000e+00\n",
"03 58 3.417896e+06 2.734316e+06 -6.835791e+05\n",
"02 39 2.412989e+06 1.930391e+06 -4.825978e+05\n",
"04 34 1.916946e+06 1.533556e+06 -3.833891e+05\n",
"39 7 1.572856e+06 1.572856e+06 0.000000e+00\n",
"23 7 1.375878e+06 1.238290e+06 -1.375878e+05\n",
"34 5 1.219782e+06 1.097804e+06 -1.219782e+05\n",
"29 7 8.124690e+05 8.124690e+05 0.000000e+00\n",
"91 5 4.057849e+05 4.057849e+05 0.000000e+00\n",
"21 4 3.350857e+05 3.350857e+05 0.000000e+00\n",
"24 2 2.737838e+05 2.737838e+05 0.000000e+00\n",
"41 1 9.132337e+04 9.132337e+04 0.000000e+00\n"
]
}
],
"source": [
"def get_vulnerability_factor_coded(mat: str | int | None) -> float:\n",
" \"\"\"Return a vulnerability factor based on the coded material type.\"\"\"\n",
" if mat is None:\n",
" return 1.0\n",
"\n",
" mapping = {\n",
" \"10\": 1.2,\n",
" \"09\": 1.1,\n",
" \"12\": 1.1,\n",
" \"00\": 1.0,\n",
" \"90\": 1.0,\n",
" \"19\": 1.0,\n",
" \"29\": 1.0,\n",
" \"39\": 1.0,\n",
" \"49\": 1.0,\n",
" \"91\": 1.0,\n",
" \"21\": 1.0,\n",
" \"24\": 1.0,\n",
" \"41\": 1.0,\n",
" \"13\": 0.9,\n",
" \"14\": 0.9,\n",
" \"30\": 0.9,\n",
" \"40\": 0.9,\n",
" \"23\": 0.9,\n",
" \"34\": 0.9,\n",
" \"01\": 0.8,\n",
" \"02\": 0.8,\n",
" \"20\": 0.8,\n",
" \"03\": 0.8,\n",
" \"04\": 0.8,\n",
" }\n",
"\n",
" return mapping.get(str(mat).strip(), 1.0)\n",
"\n",
"batiments_pts[\"vulnerability_factor\"] = batiments_pts[\"MAT_TOITS\"].apply(\n",
" get_vulnerability_factor_coded,\n",
")\n",
"batiments_pts[\"perte_affinee\"] = (\n",
" batiments_pts[\"perte_economique\"] * batiments_pts[\"vulnerability_factor\"]\n",
")\n",
"batiments_pts[\"variation_perte\"] = (\n",
" batiments_pts[\"perte_affinee\"] - batiments_pts[\"perte_economique\"]\n",
")\n",
"\n",
"\n",
"batiments_pts[\"vulnerability_factor\"] = batiments_pts[\"MAT_TOITS\"].apply(\n",
" get_vulnerability_factor_coded,\n",
")\n",
"\n",
"batiments_pts[\"perte_affinee\"] = (\n",
" batiments_pts[\"perte_economique\"] * batiments_pts[\"vulnerability_factor\"]\n",
")\n",
"\n",
"stats_mat = (\n",
" batiments_pts.groupby(\"MAT_TOITS\")\n",
" .agg({\"ID\": \"count\", \"perte_economique\": \"sum\", \"perte_affinee\": \"sum\"})\n",
" .rename(columns={\"ID\": \"nb_batiments\"})\n",
")\n",
"\n",
"stats_mat[\"variation_perte\"] = (\n",
" stats_mat[\"perte_affinee\"] - stats_mat[\"perte_economique\"]\n",
")\n",
"\n",
"print(stats_mat.sort_values(by=\"perte_economique\", ascending=False))\n"
]
},
{
"cell_type": "markdown",
"id": "f73fe2d8",
"metadata": {},
"source": [
"### Piste 2 : Analyse de l'impact de la hauteur des bâtiments"
]
},
{
"cell_type": "code",
"execution_count": 111,
"id": "ca0cab06",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Ratio de perte global : 75.56%\n",
"Nombre de bâtiments en perte quasi-totale (DR >= 80%) : 62112\n",
"PML 95% (Seuil des 5% des pertes les plus élevées) : 347,898.31 €\n"
]
}
],
"source": [
"perte_totale = batiments_pts[\"perte_affinee\"].sum()\n",
"valeur_totale = batiments_pts[\"valeur_assuree\"].sum()\n",
"loss_ratio_global = (perte_totale / valeur_totale) * 100\n",
"\n",
"nb_total_loss = len(batiments_pts[batiments_pts[\"dr\"] >= 0.8])\n",
"\n",
"p95_loss = batiments_pts[\"perte_affinee\"].quantile(0.95)\n",
"\n",
"print(f\"Ratio de perte global : {loss_ratio_global:.2f}%\")\n",
"print(f\"Nombre de bâtiments en perte quasi-totale (DR >= 80%) : {nb_total_loss}\")\n",
"print(f\"PML 95% (Seuil des 5% des pertes les plus élevées) : {p95_loss:,.2f} €\")\n"
]
},
{
"cell_type": "markdown",
"id": "c2e7051c",
"metadata": {},
"source": [
"### Piste 3 : Cartographie avancée et communication"
]
},
{
"cell_type": "code",
"execution_count": 112,
"id": "8b77dfe6",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Une hausse de 10% du vent entraîne une hausse de 17.34% des pertes.\n"
]
}
],
"source": [
"batiments_pts[\"vitesse_vent_stress\"] = batiments_pts[\"vitesse_vent\"] * 1.10\n",
"\n",
"batiments_pts[\"dr_stress\"] = batiments_pts[\"vitesse_vent_stress\"].apply(\n",
" get_damage_ratio,\n",
")\n",
"perte_stress = (batiments_pts[\"dr_stress\"] * batiments_pts[\"valeur_assuree\"]).sum()\n",
"\n",
"augmentation_percent = ((perte_stress - perte_totale) / perte_totale) * 100\n",
"print(\n",
" f\"Une hausse de 10% du vent entraîne une hausse de {augmentation_percent:.2f}% des pertes.\",\n",
")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f29f0d29",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "studies (3.13.9)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.13.9"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

2642
uv.lock generated

File diff suppressed because it is too large Load Diff