Statistics Functions API
statistics_functions
Statistics functions for PyPSA validation processing.
Each function in this module corresponds to one IAMC variable and extracts
the relevant value from a given PyPSA Network. The functions are
looked up by name via the mapping defined in configs/mapping.default.yaml.
For statistics-functions, the fixed input is n = pypsa.Network (one network / investment year) and aggregate_per_year: bool = True to switch between yearly aggregation and full snapshot time series.
If a variable-specific function needs additional settings, optional function parameters can be added.
Currently, these include config and energy totals. The functions signature is identified
automatically.
Each function returns a :class:pandas.Series with MultiIndex, holding at
least the indexes location and unit (for aggregate_per_year = True)
or a :class:pandas.DataFrame with MultiIndex and snapshots as columns
(for aggregate_per_year = False).
Region Level:
Regions in the returned Series correspond to the network's bus regions
(e.g., "AT1", "AT2", "AT3" for pypsa-at). The postprocessing layer in
Network_Processor handles aggregation to country level or keeps regions
based on the aggregation_level configuration by the name of the entries of location. All regions starting with the given country-entry are grouped together.
UNITS_MAPPING = {'MWh_el': 'MWh', 'MWh_LHV': 'MWh', 'MWh_th': 'MWh', 'land transport': 'MWh', 't_co2': 't', '': '', 'MWh': 'MWh'}
module-attribute
kwargs = {'groupby': ['location', 'unit'], 'nice_names': False}
module-attribute
kwargs_filtering = {'groupby': ['name', 'bus', 'carrier', 'location', 'unit'], 'nice_names': False}
module-attribute
kwargs_imports = {'groupby': ['bus0', 'bus1', 'unit'], 'nice_names': False}
module-attribute
Final_Energy_by_Carrier__Coal(n: pypsa.Network, aggregate_per_year: bool = True) -> pd.Series | pd.DataFrame | None
Extracts Final Energy [by Carrier]|Coal from the PyPSA Network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
Network
|
PyPSA network to process. |
required |
aggregate_per_year
|
bool
|
If |
True
|
Returns:
| Type | Description |
|---|---|
Series | DataFrame | None
|
Pandas Series ( |
Notes
This function includes only the Final Energy consumption of coal. This excludes
coal for electricity or CHP, but only focuses on the carrier coal for industry
as Final Energy of Coal. Return None, if this carrier is not present in the network.
Final_Energy_by_Carrier__District_Heat(n: pypsa.Network, aggregate_per_year: bool = True) -> pd.Series | pd.DataFrame
Extract Final Energy of District Heat from PyPSA Network.
Returns the total final energy demand, district heating facilities have to provide district heating.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
Network
|
PyPSA network to process. |
required |
aggregate_per_year
|
bool
|
If |
True
|
Returns:
| Type | Description |
|---|---|
Series | DataFrame
|
Pandas Series ( |
Notes
The energy demand of district heating is calculated based on the links from other carriers buses to the urban central heat buses. This includes waste heat from eg. DAC. Taking the withdrawal from the source bus of the link gives the energy in elem of the source carrier.
Final_Energy_by_Carrier__Electricity(n: pypsa.Network, aggregate_per_year: bool = True) -> pd.Series | pd.DataFrame
Extract electricity-carrier final energy from a PyPSA Network.
Returns the total final energy demand supplied by electricity across agriculture, residential and commercial, transportation, and industry and DAC.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
Network
|
PyPSA network to process. |
required |
aggregate_per_year
|
bool
|
If |
True
|
Returns:
| Type | Description |
|---|---|
Series | DataFrame
|
Pandas Series ( |
Notes
Combines electricity withdrawals from the following contributions: agriculture electricity loads, residential/commercial low-voltage loads (excluding dedicated industry/agriculture/charger/distribution categories, BEV charging) industry electricity loads, and DAC electricity demand change in home battery is of magnitude 1e-9 compared to electricity demand. Concerning heat: rural air heat pump, rural ground heat pump, rural resisive heater and urban decentral heatings are included. Central heatings using electricity as fuel are NOT included.
Final_Energy_by_Carrier__Natural_Gas(n: pypsa.Network, aggregate_per_year: bool = True) -> pd.Series | pd.DataFrame
Extract natural-gas final energy from a PyPSA Network.
Returns the total final energy demand supplied by natural gas across residential and commercial buildings and industry, while subtracting the estimated non-fossil share of gas consumption.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
Network
|
PyPSA network to process. |
required |
aggregate_per_year
|
bool
|
If |
True
|
Returns:
| Type | Description |
|---|---|
Series | DataFrame
|
Pandas Series ( |
Notes
The function combines residential and commercial gas withdrawals with industry gas demand, then scales the total by the fossil fraction of gas. The fossil fraction is estimated from the ratio of non-fossil gas production to total gas usage, excluding pipeline flows and limiting the non-fossil share to at most 1. Industry gas demand is reduced by a fixed non-energy-use share for EU-27 based on Eurostat energy balance data.
Final_Energy_by_Carrier__Oil(n: pypsa.Network, aggregate_per_year: bool = True) -> pd.Series | pd.DataFrame
Extract fossil final-energy oil demand from a PyPSA Network.
Returns the final energy from oil carriers after removing an estimated renewable-oil share.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
Network
|
PyPSA network to process. |
required |
aggregate_per_year
|
bool
|
If |
True
|
Returns:
| Type | Description |
|---|---|
Series | DataFrame
|
Fossil oil final energy with MultiIndex including |
Notes
Total oil final energy is built from: - agriculture machinery oil (Load), - residential/commercial oil boiler demand (rural + urban decentral), - land transport oil (Load).
naphtha for industry is intentionally excluded because it is treated
as non-energy use and therefore not part of Final Energy variables.
Regionalization from the copperplate topology is performed by deriving a
region code from demand- or production-bus names and applying
:func:create_location_index_from_copperplate before regrouping to
kwargs["groupby"].
The renewable-oil fraction is computed per region as:
renewable oil production in region / total oil demand in region.
Renewable production is based on supply from selected renewable-oil carriers, while total oil demand is based on withdrawals from oil-using carriers. If the fraction exceeds 1 (i.e., renewable production is larger than regional oil demand), it is clipped to 1, so the fossil share becomes zero in that region. Cross-regional export/import effects of renewable oil are not represented in this statistic.
UNITS_MAPPING is applied inside this function to enable multiplication
with demand-side units of the renewable-oil fraction.
Final_Energy_by_Sector__Agriculture(n: pypsa.Network, aggregate_per_year: bool = True) -> pd.Series | pd.DataFrame
Extract agriculture-sector final energy from a PyPSA Network.
Returns the total energy consumed by the transportation sector (excluding transmission / distribution losses) across the pypsa-network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
Network
|
PyPSA network to process. |
required |
aggregate_per_year
|
bool
|
If |
True
|
Returns:
| Type | Description |
|---|---|
Series | DataFrame
|
Pandas Series ( |
Notes
Includes carriers ['agriculture electricity','agriculture heat','agriculture machinery electric', 'agriculture machinery oil'] executed on Load-Components. Agriculture machinery oil is also carrier of Links and Buses, as Demand is assumed fixed. Time series of Agriculture demand are assumed to be constant in PyPSA-EUR. Theoretically, machinery oil is a single bus with load and links for energy flow. This bus could be sourced by a bus representing oil usage with carbon capture in agriculture. Therefore the "efficiency loss" of this link must be added.
Final_Energy_by_Sector__Industry(n: pypsa.Network, aggregate_per_year: bool = True) -> pd.Series | pd.DataFrame
Extract Industry-sector final energy from a PyPSA Network.
Returns the total energy consumed by the Industry sector (excluding transmission / distribution losses)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
Network
|
PyPSA network to process. |
required |
aggregate_per_year
|
bool
|
If |
True
|
Returns:
| Type | Description |
|---|---|
Series | DataFrame
|
Pandas Series ( |
Notes
Includes all carriers directly connected to loads in the industry sector. Same Carrier names are also attached to some links, so components-grouping is needed! efficiency losses directly supplying industry loads for gas, biomass and coal carbon capture are included extra.
Final_Energy_by_Sector__Residential_and_Commercial(n: pypsa.Network, aggregate_per_year: bool = True) -> pd.Series | pd.DataFrame
Extract residential and commercial-sector final energy from a PyPSA Network.
Returns the total energy consumed by the sector residentials and commercials across the pypsa-network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
Network
|
PyPSA network to process. |
required |
aggregate_per_year
|
bool
|
If |
True
|
Returns:
| Type | Description |
|---|---|
Series | DataFrame
|
Pandas Series ( |
Notes
excludes EV-charging, as covered by Sector Transportation. Concerning Carrier heat, the Function distinguishes between central heating systems (Final Energy is Heat) and decentral heating systems (Final Energy is Electricity, Gas, Liquids or Solids).
Final_Energy_by_Sector__Transportation(n: pypsa.Network, aggregate_per_year: bool = True, energy_totals: Path | None = None) -> pd.Series | pd.DataFrame
Extract transportation-sector final energy from a PyPSA Network.
Returns the total energy consumed by the Transportation sector (excluding transmission / distribution losses) across the pypsa-network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
Network
|
PyPSA network to process. |
required |
aggregate_per_year
|
bool
|
If |
True
|
energy_totals
|
Path | None
|
Path to an energy totals file used to determine domestic shares for
aviation and navigation liquid fuels. If |
None
|
Returns:
| Type | Description |
|---|---|
Series | DataFrame
|
Pandas Series ( |
Notes
Sums transportation final energy from electricity, hydrogen, and liquid fuels: - Electricity demand from BEV charging loads. - Additional EV charging losses computed from BEV charger link flows and adjusted for V2G participation. - Hydrogen demand from fuel-cell land transport. - Liquid fuels for aviation and navigation scaled by domestic fractions, plus land-transport oil.
Raises:
| Type | Description |
|---|---|
ValueError
|
If BEV charging flow sign conventions are violated. |
TypeError
|
If intermediate statistics return mixed result types. |
Net_Imports__Electricity(n: pypsa.Network, aggregate_per_year: bool = True) -> pd.Series | pd.DataFrame
Extract net imports of electricity from a PyPSA Network.
Evaluation of imports is performed on regional level, national level is covered as a result of aggregation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
Network
|
PyPSA network to process. |
required |
aggregate_per_year
|
bool
|
If |
True
|
Returns:
| Type | Description |
|---|---|
Series | DataFrame
|
Pandas Series ( |
Notes
The evaluation pathway in this function strongly depends on the input of the
parameter aggregate_per_year. Non-aggregated data (with aggregate_per_year is False)
are processed as :class:pandas.DataFrame in long-format, aggregated data
(with aggregate_per_year is True) are processed as they come.
Net_Imports__Oil(n: pypsa.Network, aggregate_per_year: bool = True) -> pd.Series | pd.DataFrame
Extract net oil imports from a PyPSA Network.
Calculates the net imports of oil by computing the difference between imports to and exports from each location based on Link components.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
Network
|
PyPSA network to process. |
required |
aggregate_per_year
|
bool
|
If |
True
|
Returns:
| Type | Description |
|---|---|
Series | DataFrame
|
Pandas Series ( |
Notes
All oil is distributed from cupperplate at "EU oil" bus. Oil link know both direction and multiple carriers are covered by these links, as these links are not just representing transmission, but also technologies with efficiencies.
Locations are derived from bus names and assigned to the respective bus columns.
The evaluation pathway in this function strongly depends on the input of the
parameter aggregate_per_year. Non-aggregated data (with aggregate_per_year is False)
are processed as :class:pandas.DataFrame in long-format, aggregated data
(with aggregate_per_year is True) are processed as they come.
create_location_index_from_copperplate(raw_input: pd.Series | pd.DataFrame, usage_location_list: list, column_name: str = 'location')
Replace the values of level column_name of an indexed object. Default
column_name to be replaced is "location" for backward compatibility.
This helper rebuilds the index of raw_input from its index frame and
overwrites the column_name column with values from
usage_location_list. It is mainly used when location information from
a copperplate-carrier result must be mapped back to explicit regional labels.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
raw_input
|
Series or DataFrame
|
Input object with a (Multi)Index that includes a |
required |
usage_location_list
|
list
|
New location values to assign row-by-row. Must have the same length as
|
required |
column_name
|
str
|
Name of the index level to replace, by default "location". |
'location'
|
Returns:
| Type | Description |
|---|---|
Series or DataFrame
|
A copy of |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
ValueError
|
If |
get_energy_totals_domestic_share(energy_totals: Path, kind: str) -> pd.Series
Return the domestic share of energy totals for a given kind.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
energy_totals
|
Path
|
Path to the energy totals csv file. |
required |
kind
|
str
|
The kind of energy totals to calculate the factor for. |
required |
Returns:
| Type | Description |
|---|---|
Series
|
The share of national aviation or navigation per country. |
remap_unit_index(series: pd.Series | pd.DataFrame, unit_mapping: dict = UNITS_MAPPING) -> pd.Series | pd.DataFrame
Remaps unit index to standard value for statistics with need for direct comparison of input-output flows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
series
|
Series | DataFrame
|
A series with a MultiIndex with a |
required |
unit_mapping
|
dict
|
Dictionary with old unit values as keys and new unit values as values, by default UNITS_MAPPING |
UNITS_MAPPING
|
Returns:
| Type | Description |
|---|---|
Series | DataFrame
|
A series with a MultiIndex with a |