def npv_weighted(x, first_year, last_year, w1, w2, w1_function, w2_function, r): if min(x.index) > first_year or max(x.index) < last_year: return np.nan x[first_year] = pyam.fill_series(x, first_year) x[last_year] = pyam.fill_series(x, last_year) years = [ i for i in x.index if i >= first_year and i <= last_year and ~np.isnan(x[i]) ] years.sort() # loop over years if not np.isnan(x[first_year]) and not np.isnan(x[last_year]): value = 0 for (i, yr) in enumerate(years[:-1]): next_yr = years[i + 1] dt = next_yr - yr if dt not in w1.keys(): w1[dt] = w1_function(r, dt) if dt not in w2.keys(): w2[dt] = w2_function(r, dt) # the summation is shifted to include the first year fully in sum, # otherwise, would return a weighted average of `yr` and `next_yr` value += w1[dt] * x[yr] + w2[dt] * x[next_yr] # the loop above does not include the last element in range `last_year`, # therefore added explicitly value += x[last_year] return value / (last_year - first_year + 1)
def test_fill_series_datetime(): # note that the series is not order and the index is defined as float y = pd.Series( data=[3, 1], index=[datetime.datetime(2001, 1, 1), datetime.datetime(2003, 1, 1)] ) assert fill_series(y, datetime.datetime(2002, 1, 1)) == 2.
def test_fill_series_out_of_range(): y = pd.Series(data=[np.nan, 1, 3, 1], index=[2002.0, 2005.0, 2007.0, 2013.0]) assert fill_series(y, 2001) is np.nan
def test_fill_series(): # note that the series is not order and the index is defined as float y = pd.Series(data=[np.nan, 1, 4, 1], index=[2002.0, 2008.0, 2005.0, 2013.0]) assert fill_series(y, 2006) == 3.0