@@ -217,56 +217,44 @@ def _npv_group(group, disc):
217217
218218 @staticmethod
219219 def _calc_npv_cash_flows (
220- cash_flows : pd .DataFrame | pd . Series ,
220+ cash_flows : pd .Series ,
221221 start_date : datetime .date ,
222222 disc_rates : DiscRates | None = None ,
223- ):
223+ ) -> pd . Series :
224224 """Apply discount rate to cash flows.
225225
226226 If it is defined, applies a discount rate `disc` to a given cash flow
227- `cash_flows` assuming present year corresponds to `start_date` .
227+ `cash_flows` using `start_date` as the reference year .
228228
229229 Parameters
230230 ----------
231231 cash_flows : pd.DataFrame
232232 The cash flow to apply the discount rate to.
233233 start_date : datetime.date
234234 The date representing the present.
235- end_date : datetime.date, optional
236235 disc : DiscRates, optional
237- The discount rate to apply.
236+ The discount rates to apply.
238237
239238 Returns
240239 -------
241240
242- A dataframe (copy) of `cash_flows` where values are discounted according to `disc`.
241+ A Series (copy) of `cash_flows` where values are discounted according to `disc`.
243242
244243 """
245244
246- if not disc_rates :
245+ if disc_rates is None :
247246 return cash_flows
248247
249248 if not isinstance (cash_flows .index , (pd .PeriodIndex , pd .DatetimeIndex )):
250249 raise ValueError (
251250 "cash_flows must be a pandas Series with a PeriodIndex or DatetimeIndex"
252251 )
253252
254- metric_df = cash_flows .to_frame (name = "cash_flow" ) # type: ignore
255- metric_df ["year" ] = metric_df .index .year
256-
257- # Merge with the discount rates based on the year
258- tmp = pd .Series (index = disc_rates .years , data = disc_rates .rates , name = "rate" )
259- tmp = tmp .loc [tmp .index >= start_date .year ]
260- tmp = 1 / tmp .shift (1 , fill_value = 0 ).add (1 ).cumprod ()
261- tmp = tmp .to_frame ()
262- tmp ["year" ] = tmp .index
263- metric_df = metric_df .merge (
264- tmp ,
265- on = "year" ,
266- how = "left" ,
253+ growth_factors = (
254+ pd .Series (disc_rates .rates , index = disc_rates .years )
255+ .loc [lambda x : x .index > start_date .year ]
256+ .add (1 )
257+ .cumprod ()
267258 )
268-
269- # Apply the discount factors to the cash flows
270-
271- metric_df ["npv_cash_flow" ] = metric_df ["cash_flow" ] * metric_df ["rate" ]
272- return metric_df ["npv_cash_flow" ].values
259+ discount_factors = 1 / cash_flows .index .year .map (growth_factors ).fillna (1.0 )
260+ return cash_flows .multiply (discount_factors , axis = 0 )
0 commit comments