@@ -150,7 +150,7 @@ def return_periods(self) -> Iterable[int]:
150150
151151 @return_periods .setter
152152 def return_periods (self , value , / ):
153- if not isinstance (value , list ):
153+ if not isinstance (value , Iterable ):
154154 raise ValueError ("Return periods need to be a list of int." )
155155 if any (not isinstance (i , int ) for i in value ):
156156 raise ValueError ("Return periods need to be a list of int." )
@@ -256,19 +256,18 @@ def _calc_npv_cash_flows(
256256 metric_df ["year" ] = metric_df .index .year
257257
258258 # Merge with the discount rates based on the year
259- tmp = metric_df .merge (
260- pd .DataFrame ({"year" : disc_rates .years , "rate" : disc_rates .rates }),
259+ tmp = pd .Series (index = disc_rates .years , data = disc_rates .rates , name = "rate" )
260+ tmp = tmp .loc [tmp .index >= start_date .year ]
261+ tmp = 1 / tmp .shift (1 , fill_value = 0 ).add (1 ).cumprod ()
262+ tmp = tmp .to_frame ()
263+ tmp ["year" ] = tmp .index
264+ metric_df = metric_df .merge (
265+ tmp ,
261266 on = "year" ,
262267 how = "left" ,
263268 )
264- tmp .index = metric_df .index
265- metric_df = tmp .copy ()
266- metric_df ["discount_factor" ] = (1 / (1 + metric_df ["rate" ])) ** (
267- metric_df .index .year - start_date .year
268- )
269269
270270 # Apply the discount factors to the cash flows
271- metric_df ["npv_cash_flow" ] = (
272- metric_df ["cash_flow" ] * metric_df ["discount_factor" ]
273- )
274- return metric_df ["npv_cash_flow" ]
271+
272+ metric_df ["npv_cash_flow" ] = metric_df ["cash_flow" ] * metric_df ["rate" ]
273+ return metric_df ["npv_cash_flow" ].values
0 commit comments