We're hiring
Back to blog

Polars helps coping with black swan events at La Mobilière

Thu, 9 Oct 2025

About La Mobilière

La Mobilière is a leading life and non-life insurance company in Switzerland with a long-standing tradition dating back to 1826. As one of the biggest cooperative insurance companies in Switzerland our core values are: human-centered, accessible and trustworthy, thus upholding our promise cannot be compromised.

banner La Mobiliere

How Polars Helps Keep Our Promise

La Mobilière must honor its promise to reimburse policyholders in the event of a loss—even in challenging years when difficulties affect many, not just a few individuals.

Just like an individual relies on a rainy-day fund, insurance companies need to set aside reserves to cover potential losses. The actuarial department at La Mobilière computes how much to set aside, striking a careful balance: holding enough to meet obligations even in the worst years, while not locking away so much that we miss valuable investment opportunities. To ensure companies do not set aside too little, regulators impose capital requirements—known as the Swiss Solvency Test (SST) in Switzerland, and Solvency II in the EU.

The SST is a very important process in the reserving department at La Mobilière. A key step in the process is the modeling of catastrophic years. To strengthen this step, we rewrote our simulation engine from the ground up using Polars. We are extremely happy with the outcome: our models are now more intuitive, scale better and run 5–10x faster than our previous ones, which relied heavily on pandas.

Polars was key in making, implementing and running our risk models. Thanks to Polars the process became highly enjoyable, mostly due to its clean and intuitive API as well as fast query execution.

Christian Lorentzen, PhD
Chief non-life reserving actuary at la Mobilière

The Backbone of Our Simulation Engine

We refactored our internal risk model to utilize Polars DataFrames as the core data structure. This change has been transformative, allowing us to work with highly granular datasets at an unprecedented scale. Previously, we had to aggregate individual module results early on to avoid memory constraints and long runtimes—losing out on valuable analysis opportunities. A sample DataFrame is shown in Fig. 1.

Image of dataframe with simulated data

Figure 1: Example DataFrame used for risk modelling with Polars (data shown is synthetic and simplified).

For each simulated year, we capture losses across multiple lines of business, risk types, and even multiple loss events. At 1 million simulation years, the resulting DataFrame can easily exceed 100 million rows. This scale was previously unfeasible.

Actuaries typically run these simulations on their laptops, which made a large number of simulation years unfeasible with our previous pandas-based solution. We also couldn’t fully leverage the cloud, since pandas primarily runs on a single core—meaning that scaling up to large single-node instances mostly just increased our compute bill. Polars, by contrast, natively utilizes all cores on a machine, allowing us to take real advantage of cloud computing.

A large number of simulation years is essential to get reliable tail statistics to account for the Black Swan years where everything goes down the drain.

As shown in Fig. 1, we use individual modules to simulate the different types of risk. For instance:

  • Attritional Claims represent routine day-to-day losses (e.g. minor car accidents) at a yearly level.
  • Large Claims represents infrequent but individually significant losses (e.g. fire in a parking garage).
  • Catastrophic Claims represent rare, severe events that often impact many insured parties at once (e.g. a severe hailstorm).

For analysis and reporting, we compute statistics across different types of claims and lines of business. One key metric in risk management is the expected shortfall, or tail value at risk (TVaR)—the mean of the worst 1% of losses.

With Polars, these calculations are both simple and efficient thanks to its expressive API and ability to filter within a groupby. This feature, which we use extensively, makes computing TVaR straightforward (see Polars example), whereas achieving the same result in pandas required far more complex code (see pandas example).

# Compute statistics of the output including the tail value at risk (TVaR) with Polars

# making use of Polars' expressions
top_losses_condition = pl.col("Loss") > pl.col("Loss").quantile(0.99)

df.group_by("LoB").agg(
    mean=pl.col("Loss").mean(),
    q99=plcol("Loss").quantile(0.99),
    # filtering within an aggregation
    tvar=pl.col("Loss").filter(top_losses_condition).mean()
)

Polars example: Calculating the tail value at risk (TVaR) in a group_by using the filter() function.

# Compute statistics of the output including TVaR with pandas

# Step 1: Grouped quantities on the whole dataset
df_agg = dfp.groupby("LoB", as_index=False).agg(
    mean=("Loss", "mean"),
    q99=("Loss", lambda x: x.quantile(0.99))
)

# Step 2: Tail mean (TVaR)
def tail_mean(group):
    treshold = group["Loss"].quantile(0.99)
    return group.loc[group["Loss"] > treshold, "Loss"].mean()

tvar_df = dfp.groupby("LoB").apply(tail_mean).reset_index(name="tvar")

# Step 3: Join the results
df_aggp.merge(tvar_df, on="LoB")

pandas example: Computing the TVaR in pandas previously required a double groupby and a join to put the result together with the other aggregated statistics.

Conclusion

Polars has greatly enhanced our risk modeling capabilities and our ability to analyze risk, while making our code faster, more efficient, and easier to understand. It is thrilling to witness the evolution of Polars and how it will assist us in addressing the insured risks of our policyholders, enabling us to offer prompt assistance and financial support in times of need. We would like to extend our sincere gratitude to the Polars community and hope that many others embrace Polars in their projects.

About the authors

This post is written by Dr. Santiago Padrón and Dr. Michael Tomka.

https://www.mobiliar.ch/ueber-uns/karriere

1
2
4
3
5
6
7
8
9
10
11
12