Skip to content

ENH: Allow npv calculation to be broadcastable #54

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 19, 2022
Merged

ENH: Allow npv calculation to be broadcastable #54

merged 1 commit into from
Apr 19, 2022

Conversation

Kai-Striega
Copy link
Member

This PR applies broadcasting operations to npv calculations. This is significantly faster than iterating over an array of cashflows as is shown by the below code snippet.

import numpy as np
from numpy.testing import assert_allclose
import numpy_financial as npf

import time


def faster_npv(rate: float, values: np.ndarray):
    """ A faster way to calculate NPV for several projects based
    on numpy arrays. """
    values = np.atleast_2d(values)
    timestep_array = np.arange(0, values.shape[1])
    npv = (values / (1 + rate) ** timestep_array).sum(axis=1)
    try:
        # If size of array is one, return scalar
        return npv.item()
    except ValueError:
        # Otherwise, return entire array
        return npv


if __name__ == "__main__":
    rate = 0.05
    no_simulations = int(1e6)
    lifetime = 10  # years

    capex = np.random.normal(loc=1000, scale=100, size=no_simulations)
    opex = np.random.normal(loc=100, scale=10, size=no_simulations)
    values = np.array([capex] + [opex] * lifetime).transpose()

    start_time = time.time()
    all_npv_slow = [npf.npv(rate, values[i]) for i in range(no_simulations)]
    print(f"Standard NPF calculations took {time.time() - start_time}s.")

    start_time = time.time()
    all_npv_fast = faster_npv(rate, values)
    print(f"Faster NPV calculations took {time.time() - start_time}s.")

    assert_allclose(all_npv_fast, all_npv_slow)

closes #52

@Kai-Striega Kai-Striega added the enhancement New feature or request label Apr 16, 2022
@Kai-Striega
Copy link
Member Author

pinging @jowahlin does this look good to you?

@Kai-Striega Kai-Striega merged commit d24fa09 into numpy:master Apr 19, 2022
@Kai-Striega Kai-Striega deleted the faster_npv branch April 19, 2022 10:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Slow NPV calculations for monte carlo simulation purposes
1 participant