Python for Financial Modelling: Getting Started
Where Python beats Excel for modelling — scenario analysis, Monte Carlo, reusability — and a worked DCF example with numpy-financial.
Python isn't trying to replace Excel for financial modelling — for a single, one-off model that a non-technical stakeholder needs to open, inspect and tweak themselves, Excel still wins. Python earns its place when a model needs to run many times with different assumptions, or when the same modelling logic gets reused across multiple projects rather than rebuilt from scratch each time.
When Python actually beats Excel here
Three situations in particular. Scenario analysis at scale: testing a model against fifty or five hundred combinations of assumptions is a loop in Python and a genuinely painful exercise in Excel, even with data tables. Monte Carlo simulation: running a model thousands of times with randomly sampled inputs to build a distribution of outcomes is something Excel can technically do but Python does natively and fast. And reusability: a modelling approach that gets applied to a new deal or a new project every quarter benefits from being a documented, version-controlled function rather than a copy-pasted spreadsheet that drifts slightly each time someone adapts it.
numpy-financial for the core time-value-of-money functions
The numpy-financial package covers the standard building blocks directly: npf.npv(rate, cashflows) for net present value, npf.irr(cashflows) for internal rate of return, npf.pmt(rate, nper, pv) for a loan or lease payment. These map directly onto Excel's NPV, IRR and PMT functions — the underlying finance is identical, only the interface changes.
A simple DCF model in Python
import numpy_financial as npf
cash_flows = [-500000, 120000, 135000, 150000, 160000, 175000]
discount_rate = 0.10
npv = npf.npv(discount_rate, cash_flows)
irr = npf.irr(cash_flows)
That's a complete five-year discounted cash flow model — initial outlay followed by five years of projected cash flow, discounted back at 10%. The structure mirrors exactly what you'd build in Excel: a list of cash flows and a discount rate. The difference shows up in what happens next.
Sensitivity analysis without rebuilding anything
Wrap the same calculation in a loop over a range of discount rates, and you get a full sensitivity table in a few lines: for rate in [0.08, 0.09, 0.10, 0.11, 0.12]: print(rate, npf.npv(rate, cash_flows)). Extend that to looping over two variables at once (discount rate and an initial outlay range, say) and you have a two-way sensitivity table that would otherwise need Excel's Data Table feature, which recalculates the whole workbook for each combination and gets slow fast on anything complex.
Where Excel still wins for modelling
Auditability, mainly. A well-built Excel model shows its formulas in place — click a cell, see exactly what feeds it. A Python script hides that structure unless the person reading it can also read Python, which most finance stakeholders reviewing a model can't. If a model needs to be handed off to someone else to inspect, adjust, and sign off on without touching code, Excel remains the better format. Python modelling suits the analysis and scenario-testing phase; the version someone external actually reviews often still needs to be a spreadsheet, sometimes generated directly from the Python model's outputs.
Getting started without overcomplicating it
Start with numpy-financial for the core calculations and pandas to structure your inputs and assumptions cleanly — a DataFrame of scenarios is easier to reason about than a wall of loose variables. Resist the urge to build a fully general modelling framework on day one; get one specific model (a DCF, a loan schedule, a simple valuation) working correctly for your actual use case before generalising it. A working, specific model beats an ambitious, half-finished general one every time.
Where this connects
Structuring model inputs and outputs uses the same pandas techniques as Python pandas for finance, and once a model is producing scenario results, good data visualization principles apply just as much to presenting model outputs as they do to any other financial chart — a sensitivity table nobody can read at a glance hasn't actually communicated the analysis.
Running a basic Monte Carlo simulation
This is the clearest case where Python's advantage over Excel is hard to argue with. Instead of a single discount rate, sample thousands of plausible rates from a distribution and run the NPV calculation once per sample: import numpy as np. Ten thousand NPV calculations run in well under a second, giving a full distribution of likely outcomes — a mean, a 90% confidence range — rather than a single point estimate. Building the equivalent in Excel, even with an add-in, is materially slower and harder to maintain.
rates = np.random.normal(0.10, 0.02, 10000)
results = [npf.npv(r, cash_flows) for r in rates]
print(np.mean(results), np.percentile(results, [5, 95]))
Keeping assumptions separate from calculations
The habit that makes a Python model maintainable long-term is the same one that makes a good Excel model maintainable: keep assumptions in one clearly labelled place, separate from the calculation logic itself. A dictionary or a small DataFrame of named assumptions (discount rate, growth rate, initial investment) that the calculation functions read from is far easier to update and hand off than assumptions buried inline inside formulas — in Python just as much as in a spreadsheet.
If the Python itself is the unfamiliar part, start with Python for accountants, how Python, Excel and ChatGPT fit together and the Excel modelling techniques this builds on. Our Tech and Tools CPD for accountants turns the same material into CPD-recognised hours.
This page was last updated:
Learnsignal Education Team
Expert Tutor at Learnsignal
Qualified professional with years of experience helping students advance their professional careers.
View all posts by Learnsignal Education Team

