Statistics
The statistics module is used to extract and calculate common metrics from a Network. This module is intended to simplify the process of inspecting networks and creating first visualizations of your results.
It is accessed via the n.statistics property of any pypsa.Network object.
Shorthand Alias
For convenience, n.stats is available as a shorthand alias for n.statistics. Both can be used interchangeably throughout your code.
Metrics¶
Currently supported metrics are:
- Capital expenditure: The capital expenditure of all components.
- Installed capital expenditure: The capital expenditure of all components before optimization.
- Expanded capital expenditure: The capital expenditure of all components added during optimization.
- Overnight investment cost: The overnight investment costs (excluding FOM) of all components.
- Fixed O&M: The fixed operation and maintenance costs of all components.
- Operational expenditure: The operational expenditure of all components.
- Installed capacities: The capacities of all components before optimization.
- Expanded capacities: The capacities of all components added during optimization.
- Optimal capacities: The total capacities of all components after optimization.
- Supply: The energy supplied by all components.
- Withdrawal: The energy withdrawn by all components.
- Curtailment: The energy curtailed in all components.
- Capacity Factor: The capacity factor / utilization rate of all components.
- Revenue: The revenue received by all components.
- Market value: The market value of all components.
- Energy balance: The energy balance of the network across all carriers and snapshots.
- System costs: The total system costs after optimization, including capital and operational expenditure.
- Marginal prices: The marginal prices at the buses for all snapshots.
- Transmission: The energy transmitted through transmission components (links, lines, transformers connecting to buses of the same carrier).
These metrics can be calculated using the n.statistics accessor, for instance:
>>> installed_capacity = n.statistics.installed_capacity()
>>> installed_capacity
component carrier
Generator gas 150000.0
...
dtype: float64
>>> opex = n.statistics.opex()
>>> opex
Component carrier
Generator gas 1000.0
wind 0.0
solar 0.0
Name: opex, dtype: float64
Parameters¶
Most statistics methods accept common parameters to control filtering, grouping, and output formatting.
Warning
Not all metrics support all parameters. Please check the function docstring for details.
Filtering¶
Select which components to include:
components: List of component types to include (e.g.,["Generator", "StorageUnit"])carrier: Filter by component carrier (e.g.,"wind"or["wind", "solar"])bus_carrier: Filter by connected bus carrier (e.g.,"AC")
Tip
All filtering can also be done via pandas indexing after calling the statistic method. But using the parameters is more efficient, as it avoids unnecessary calculations.
# Only generators with wind carrier on AC buses
>>> n.statistics.supply(components=["Generator"], carrier="wind", bus_carrier="AC")
Grouping¶
Control how results are grouped and aggregated:
groupby: Group by attributes or custom functions.
Built-in groupers include:
"carrier"- Group by component carrier"bus_carrier"- Group by carrier of connected bus"bus"- Group by connected bus"country"- Group by country of bus location"location"- Group by location of bus"name"- Group by component name"unit"- Group by unit
You can also use component attributes directly (e.g., "type", "p_nom"), provide custom functions, or combine multiple groupers for multi-index grouping.
groupby_method: Aggregation method like "sum", "mean", "max". Default is "sum"
Registering custom groupers¶
You can register custom groupers to use them by name in the groupby argument:
# Define a custom grouper function
def group_by_voltage(n, c, port=""):
"""Group components by voltage level of connected bus."""
bus = f"bus{port}"
buses = n.c[c].static[bus]
voltage = n.c.buses.static.v_nom.rename("voltage")
return buses.map(voltage)
# Register the grouper on module level
pypsa.statistics.groupers.add_grouper("voltage", group_by_voltage)
# Use it by name in any statistics method
n.statistics.installed_capacity(groupby="voltage")
# Or access it as attribute
n.statistics.supply(groupby=pypsa.statistics.groupers.voltage)
Custom grouper functions must:
- Accept arguments:
n(Network),c(component name),port(optional),nice_names(optional) - Return a
pd.Serieswith the same length as the component index
Time Aggregation¶
For time-varying metrics:
groupby_time: Method to aggregate over time ("sum","mean", etc.) orFalseto keep time series
>>> # Average supply per time step (empty before solving the network)
>>> n.statistics.supply(groupby_time="mean")
Series([], dtype: float64)
>>> # Get full time series (NaN until dispatch is solved)
>>> n.statistics.supply(groupby_time=False).head() # doctest: +NORMALIZE_WHITESPACE
snapshot 2015-01-01 00:00:00 ... 2015-01-01 09:00:00
component carrier ...
Generator gas NaN ... NaN
wind NaN ... NaN
Load load NaN ... NaN
[3 rows x 10 columns]
Note
Time aggregation automatically accounts for snapshot weightings when using "sum" or "mean". Other aggregation methods like "std" or "median" do not apply snapshot weightings.
Output Formatting¶
nice_names: Use nice names for carriersdrop_zero: Remove zero-value rowsround: Round to decimal places
Expressions¶
Next to the statistics module under n.statistics, there is also an experimental optimization expressions module under n.optimize.expressions. It provides similar functionality, but creates linopy expressions for the optimization model instead of calculating values from the network data.