Skip to content

Commit 596111c

Browse files
update the tutorial
1 parent eda57ca commit 596111c

File tree

1 file changed

+135
-62
lines changed

1 file changed

+135
-62
lines changed

doc/user-guide/climada_util_yearsets.ipynb

Lines changed: 135 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,21 @@
66
"source": [
77
"# Calculate probabilistic impact yearset\n",
88
"\n",
9-
"This module generates a yearly impact `yimp` object which contains probabilistic annual impacts for a specified amount of years (`sampled_years`). The impact values are extracted from a given impact `imp` object that contains impact values per event. The amount of `sampled_years` can be specified as an integer or as a list of years to be sampled for. The amount of events per sampled year (`events_per_year`) are determined with a Poisson distribution centered around n_events per year (`lam` = sum(event_impacts.frequency). Then, the probabilistic events occurring in each sampled year are sampled uniformly from the input `imp` object and summed up per year. Thus, the `yimp` object contains the sum of sampled (event) impacts for each sampled year. In contrast to the expected annual impact (eai), an `yimp` object contains an impact for EACH sampled year and this value differs among years. The number of events_per_year and the selected_events are saved in a sampling vector (`sampling_vect`). \n",
9+
"This module generates a yearly impact object `yimp` which contains probabilistic annual impacts for a specified amount of years (`sampled_years`). The impact values are extracted from a given impact `imp` object that contains impact values per event. The amount of sampled years as a list of years (`sampled_years`) to be sampled for. The amount of events per sampled year (`events_per_year`) are determined with a Poisson distribution (`lam` = sum(event_impacts.frequency)). Then, the events occurring in each sampled year are sampled from the input `imp` object and summed up per year. Thus, the `yimp` object contains the sum of sampled (event) impacts for each sampled year. In contrast to the expected annual impact (eai), an `yimp` object contains an impact for EACH sampled year and this value differs among years. The number of events_per_year and the selected_events are saved in a sampling vector (`sampling_vect`). \n",
1010
"\n",
11-
"The function impact_yearsets performs all these computational steps, taking an `imp` and the number of sampled_years (`sampled_years`) as input. The output of the function is the `yimp` object and the `sampling_vect`.\n",
12-
"Moreover, a `sampling_vect` (generated in a previous run) can be provided as optional input and the user can define `lam` and decide whether a correction factor shall be applied (the default is applying the correction factor).\n",
13-
"Reapplying the same sampling_vect does not only allow to reproduce the generated `yimp`, but also for a physically consistent way of sampling impacts caused by different hazards. \n",
14-
"The correction factor that is applied when the optional input `correction_fac`= True is a scaling of the computed `yimp` that assures that the eai(`yimp`) = eai(`imp`).\n",
11+
"The function `impact_yearset` performs all these computational steps, taking an `imp` and the list of sampled_years (`sampled_years`) as input. The output of the function is the `yimp` object and the `sampling_vect`.\n",
12+
"Moreover, a `sampling_vect` (generated in a previous run) can be provided as optional input and the user can custom-define the Poisson parameter `lam`. Reapplying the same sampling_vect does not only allow to reproduce the generated `yimp`, but also for a physically consistent way of sampling impacts caused by different hazards. \n",
1513
"\n",
14+
"*Sampling options.* Per default, impact events are sampled without replacement (if the original impact object contains enough events), such that the different yearly impacts stem from different events. This is only implemented if the event frequencies of the original impact object (`imp.frequency`) are constant. If the events differ in their frequency, they are sampled with replacement. This sampling behaviour can also be achieved by setting `with_replacement=True`. \n",
15+
"\n",
16+
"*Correction factor.* Per default, a correction factor is applied uniformly to all yearly impacts, such that the final `yimp` object has the same average annual impact than `imp`, the original impact object. When setting `correction_fac=False`, the correction factor is not applied.\n",
17+
"\n"
18+
]
19+
},
20+
{
21+
"cell_type": "markdown",
22+
"metadata": {},
23+
"source": [
1624
"To make the process more transparent, this tutorial shows the single computations that are performed when generating an `yimp` object for a dummy event_impacts object. "
1725
]
1826
},
@@ -22,60 +30,79 @@
2230
"metadata": {
2331
"scrolled": true
2432
},
33+
"outputs": [],
34+
"source": [
35+
"import numpy as np\n",
36+
"import climada.util.yearsets as yearsets\n",
37+
"from climada.engine import Impact\n",
38+
"\n",
39+
"# dummy event_impacts object containing 12 event impacts\n",
40+
"imp = Impact(\n",
41+
" event_id=np.arange(6) + 10,\n",
42+
" event_name=np.arange(6) + 10,\n",
43+
" date=np.arange(6),\n",
44+
" coord_exp=np.array([[1, 2], [1.5, 2.5]]),\n",
45+
" eai_exp=np.array([13.4, 13.4]),\n",
46+
" at_event=np.array([0, 2, 4, 6, 60, 62]),\n",
47+
" frequency=np.full(6, 0.2),\n",
48+
" aai_agg=26.8,\n",
49+
")"
50+
]
51+
},
52+
{
53+
"cell_type": "markdown",
54+
"metadata": {},
55+
"source": [
56+
"### Step-by-step calculation"
57+
]
58+
},
59+
{
60+
"cell_type": "code",
61+
"execution_count": 2,
62+
"metadata": {},
2563
"outputs": [
2664
{
2765
"data": {
2866
"text/plain": [
29-
"array([2, 2, 2, 0, 4, 5, 4, 2, 3, 1])"
67+
"array([1, 3, 0, 0, 2, 0, 1, 2, 1, 3])"
3068
]
3169
},
32-
"execution_count": 1,
70+
"execution_count": 2,
3371
"metadata": {},
3472
"output_type": "execute_result"
3573
}
3674
],
3775
"source": [
38-
"import numpy as np\n",
39-
"\n",
40-
"import climada.util.yearsets as yearsets\n",
41-
"from climada.engine import Impact\n",
42-
"\n",
43-
"# dummy event_impacts object containing 10 event_impacts with the values 10-110\n",
44-
"# and the frequency 0.2 (Return period of 5 years)\n",
45-
"imp = Impact()\n",
46-
"imp.at_event = np.arange(10, 110, 10)\n",
47-
"imp.frequency = np.array(np.ones(10) * 0.2)\n",
48-
"\n",
49-
"# the number of years to sample impacts for (length(yimp.at_event) = sampled_years)\n",
50-
"sampled_years = 10\n",
76+
"# the number of years to sample impacts for (length(yimp.at_event) = n_sampled_years)\n",
77+
"n_sampled_years = 10\n",
5178
"\n",
5279
"# sample number of events per sampled year\n",
5380
"lam = np.sum(imp.frequency)\n",
54-
"events_per_year = yearsets.sample_from_poisson(sampled_years, lam)\n",
81+
"events_per_year = yearsets.sample_from_poisson(n_sampled_years, lam)\n",
5582
"events_per_year"
5683
]
5784
},
5885
{
5986
"cell_type": "code",
60-
"execution_count": 2,
87+
"execution_count": 3,
6188
"metadata": {},
6289
"outputs": [
6390
{
6491
"data": {
6592
"text/plain": [
66-
"[array([8, 3]),\n",
67-
" array([7, 0]),\n",
68-
" array([4, 6]),\n",
69-
" array([], dtype=int32),\n",
70-
" array([5, 9, 1, 2]),\n",
71-
" array([1, 6, 0, 7, 2]),\n",
72-
" array([4, 9, 5, 8]),\n",
73-
" array([9, 8]),\n",
74-
" array([5, 3, 4]),\n",
75-
" array([1])]"
93+
"[array([2]),\n",
94+
" array([0, 4, 3]),\n",
95+
" array([], dtype=int64),\n",
96+
" array([], dtype=int64),\n",
97+
" array([5, 1]),\n",
98+
" array([], dtype=int64),\n",
99+
" array([3]),\n",
100+
" array([5, 1]),\n",
101+
" array([0]),\n",
102+
" array([2, 1, 5])]"
76103
]
77104
},
78-
"execution_count": 2,
105+
"execution_count": 3,
79106
"metadata": {},
80107
"output_type": "execute_result"
81108
}
@@ -88,16 +115,16 @@
88115
},
89116
{
90117
"cell_type": "code",
91-
"execution_count": 3,
118+
"execution_count": 4,
92119
"metadata": {},
93120
"outputs": [
94121
{
95122
"data": {
96123
"text/plain": [
97-
"[130, 90, 120, 0, 210, 210, 300, 190, 150, 20]"
124+
"array([ 4, 66, 0, 0, 64, 0, 6, 64, 0, 68])"
98125
]
99126
},
100-
"execution_count": 3,
127+
"execution_count": 4,
101128
"metadata": {},
102129
"output_type": "execute_result"
103130
}
@@ -110,16 +137,16 @@
110137
},
111138
{
112139
"cell_type": "code",
113-
"execution_count": 4,
140+
"execution_count": 5,
114141
"metadata": {},
115142
"outputs": [
116143
{
117144
"data": {
118145
"text/plain": [
119-
"0.7746478873239436"
146+
"0.9852941176470589"
120147
]
121148
},
122-
"execution_count": 4,
149+
"execution_count": 5,
123150
"metadata": {},
124151
"output_type": "execute_result"
125152
}
@@ -130,65 +157,111 @@
130157
"correction_factor"
131158
]
132159
},
160+
{
161+
"cell_type": "markdown",
162+
"metadata": {},
163+
"source": [
164+
"### Direct calculation"
165+
]
166+
},
167+
{
168+
"cell_type": "markdown",
169+
"metadata": {},
170+
"source": [
171+
"If we use the same seed, the `yimp.at_event` values coincide with the step-by-step `imp_per_year` values, if no correction factor is applied."
172+
]
173+
},
133174
{
134175
"cell_type": "code",
135-
"execution_count": 5,
176+
"execution_count": 6,
136177
"metadata": {},
137178
"outputs": [
138179
{
139180
"name": "stdout",
140181
"output_type": "stream",
141182
"text": [
142-
"The yimp.at_event values equal our step-by-step computed imp_per_year:\n",
143-
"yimp.at_event = [90, 240, 150, 70, 40, 90, 60, 90, 170, 110]\n",
144-
"imp_per_year = [130, 90, 120, 0, 210, 210, 300, 190, 150, 20]\n"
183+
"yimp.at_event = [ 60 0 0 8 128 0 0 130 122 8]\n",
184+
"imp_per_year = [ 60 0 0 8 128 0 0 130 122 8]\n",
185+
"The expected annual impact 45.6 differs from the one of the original impact (26.8).\n"
145186
]
146187
}
147188
],
148189
"source": [
149-
"# compare the resulting yimp with our step-by-step computation without applying the correction factor:\n",
190+
"example_seed = 12345 # fix a seed\n",
191+
"sampled_years = list(range(2015, 2025))\n",
192+
"\n",
193+
"# direct computation\n",
150194
"yimp, sampling_vect = yearsets.impact_yearset(\n",
151-
" imp, sampled_years=list(range(1, 11)), correction_fac=False\n",
195+
" imp, sampled_years, correction_fac=False, seed=example_seed\n",
196+
")\n",
197+
"\n",
198+
"# step-by-step computation without applying the correction factor\n",
199+
"events_per_year = yearsets.sample_from_poisson(\n",
200+
" len(sampled_years), lam, seed=example_seed\n",
201+
")\n",
202+
"sampling_vect = yearsets.sample_events(\n",
203+
" events_per_year, imp.frequency, seed=example_seed\n",
152204
")\n",
205+
"imp_per_year = yearsets.compute_imp_per_year(imp, sampling_vect)\n",
206+
"\n",
153207
"\n",
154-
"print(\"The yimp.at_event values equal our step-by-step computed imp_per_year:\")\n",
155208
"print(\"yimp.at_event = \", yimp.at_event)\n",
156-
"print(\"imp_per_year = \", imp_per_year)"
209+
"print(\"imp_per_year = \", imp_per_year)\n",
210+
"print(\n",
211+
" f\"The expected annual impact {round(yimp.aai_agg,2)} differs from the one of the original impact ({round(imp.aai_agg,2)}).\"\n",
212+
")"
213+
]
214+
},
215+
{
216+
"cell_type": "markdown",
217+
"metadata": {},
218+
"source": [
219+
"Similarly, if we use the same seed, the `yimp.at_event` values when using the correction factor coincide with the step-by-step `imp_per_year` values after applyng the correction factor."
157220
]
158221
},
159222
{
160223
"cell_type": "code",
161-
"execution_count": 6,
224+
"execution_count": 7,
162225
"metadata": {},
163226
"outputs": [
164227
{
165228
"name": "stdout",
166229
"output_type": "stream",
167230
"text": [
168-
"The same can be shown for the case of applying the correction factor.The yimp.at_event values equal our step-by-step computed imp_per year:\n",
169-
"yimp.at_event = [ 54.54545455 47.72727273 95.45454545 109.09090909 0.\n",
170-
" 40.90909091 27.27272727 0. 109.09090909 27.27272727]\n",
171-
"imp_per_year = [167.81818182 116.18181818 154.90909091 0. 271.09090909\n",
172-
" 271.09090909 387.27272727 245.27272727 193.63636364 25.81818182]\n"
231+
"2025-07-17 14:56:28,995 - climada.util.yearsets - INFO - The correction factor is 0.5877192982456141.\n",
232+
"yimp.at_event = [35.26 0. 0. 4.7 75.23 0. 0. 76.4 71.7 4.7 ]\n",
233+
"imp_per_year = [35.26 0. 0. 4.7 75.23 0. 0. 76.4 71.7 4.7 ]\n",
234+
"The expected annual impact 26.8 is equal to the one of the original impact (26.8).\n"
173235
]
174236
}
175237
],
176238
"source": [
177-
"# and here the same comparison with applying the correction factor (default settings):\n",
178-
"yimp, sampling_vect = yearsets.impact_yearset(imp, sampled_years=list(range(1, 11)))\n",
239+
"# direct computation\n",
240+
"yimp, sampling_vect = yearsets.impact_yearset(\n",
241+
" imp, sampled_years, correction_fac=True, seed=example_seed\n",
242+
")\n",
179243
"\n",
244+
"# compute correction factor\n",
245+
"correction_factor = yearsets.calculate_correction_fac(imp_per_year, imp)\n",
246+
"\n",
247+
"print(\"yimp.at_event = \", np.round(yimp.at_event, 2))\n",
248+
"print(\"imp_per_year = \", np.round(imp_per_year * correction_factor, 2))\n",
180249
"print(\n",
181-
" \"The same can be shown for the case of applying the correction factor.\"\n",
182-
" \"The yimp.at_event values equal our step-by-step computed imp_per year:\"\n",
183-
")\n",
184-
"print(\"yimp.at_event = \", yimp.at_event)\n",
185-
"print(\"imp_per_year = \", imp_per_year / correction_factor)"
250+
" f\"The expected annual impact {round(yimp.aai_agg,2)} is equal to the one of the original impact ({round(imp.aai_agg,2)}).\"\n",
251+
")"
186252
]
253+
},
254+
{
255+
"cell_type": "code",
256+
"execution_count": null,
257+
"metadata": {},
258+
"outputs": [],
259+
"source": []
187260
}
188261
],
189262
"metadata": {
190263
"kernelspec": {
191-
"display_name": "Python 3 (ipykernel)",
264+
"display_name": "climada_env600",
192265
"language": "python",
193266
"name": "python3"
194267
},
@@ -202,7 +275,7 @@
202275
"name": "python",
203276
"nbconvert_exporter": "python",
204277
"pygments_lexer": "ipython3",
205-
"version": "3.8.12"
278+
"version": "3.11.11"
206279
}
207280
},
208281
"nbformat": 4,

0 commit comments

Comments
 (0)