From 40a93ef813767d633ebfa350a15d73c636326dd9 Mon Sep 17 00:00:00 2001 From: John Bogaardt Date: Thu, 13 Feb 2025 08:29:06 -0700 Subject: [PATCH] 0.8.24 bump --- chainladder/core/base.py | 4 ++-- chainladder/core/dunders.py | 15 +++++---------- chainladder/core/triangle.py | 7 +++++++ requirements.txt | 4 ++-- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/chainladder/core/base.py b/chainladder/core/base.py index f3e9401a..122e8784 100644 --- a/chainladder/core/base.py +++ b/chainladder/core/base.py @@ -90,14 +90,14 @@ def _aggregate_data(data, origin_date, development_date, index, columns): key_gr = ["__origin__", "__development__"] + [ data[item] for item in ([] if not index else index) ] - data_agg = data.groupby(key_gr)[columns].sum().reset_index().fillna(0) + data_agg = data.groupby(key_gr)[columns].sum(numeric_only=False).reset_index().fillna(0) data = data.drop(["__origin__", "__development__"], axis=1) else: # Summarize dataframe to the level specified in axes key_gr = [origin_date, development_date] + [ data[item] for item in ([] if not index else index) ] - data_agg = data[columns].groupby(key_gr).sum().reset_index().fillna(0) + data_agg = data[columns].groupby(key_gr)[columns].sum(numeric_only=False).reset_index().fillna(0) data_agg["__origin__"] = data_agg[origin_date.name] data_agg["__development__"] = data_agg[development_date.name] # origin <= development is required - truncate bad records if not true diff --git a/chainladder/core/dunders.py b/chainladder/core/dunders.py index 0b987985..137f1dd7 100644 --- a/chainladder/core/dunders.py +++ b/chainladder/core/dunders.py @@ -109,14 +109,10 @@ def _prep_columns(self, x, y): y.vdims = x.vdims elif x.shape[1] == y.shape[1] and np.array_equal(x.columns, y.columns): return x, y - else: - # Use sets for faster operations - x_cols = set(x.columns) - y_cols = set(y.columns) - + else: # Find columns to add to each triangle - cols_to_add_to_x = y_cols - x_cols - cols_to_add_to_y = x_cols - y_cols + cols_to_add_to_x = [col for col in y.columns if col not in x.columns] + cols_to_add_to_y = [col for col in x.columns if col not in y.columns] # Create new columns only if necessary if cols_to_add_to_x: @@ -128,9 +124,8 @@ def _prep_columns(self, x, y): y = y.reindex(columns=new_y_cols, fill_value=0) # Ensure both triangles have the same column order - final_cols = list(x_cols | y_cols) - x = x[final_cols] - y = y[final_cols] + x = x[new_x_cols] + y = y[new_x_cols] # Reset backends only if they've changed if x.array_backend != x_backend: diff --git a/chainladder/core/triangle.py b/chainladder/core/triangle.py index 0458b774..55303c32 100644 --- a/chainladder/core/triangle.py +++ b/chainladder/core/triangle.py @@ -981,3 +981,10 @@ def sort_axis(self, axis): obj.values = obj.values[..., list(sort)] obj.ddims = obj.ddims[list(sort)] return obj + + def reindex(self, columns=None, fill_value=np.nan): + obj = self.copy() + for column in columns: + if column not in obj.columns: + obj[column] = fill_value + return obj diff --git a/requirements.txt b/requirements.txt index e2d6a6fc..b6f6cb7c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ -pandas>=0.23 -scikit-learn>=0.23 +pandas>=2.0 +scikit-learn>1.4.2 numba>0.54 sparse>=0.9 matplotlib