Utilities
common
¶
General utility functions for PyPSA.
Classes:
-
UnexpectedError–Custom error for unexpected conditions with issue tracker reference.
Functions:
-
as_index–Return a pd.Index object from a list-like or scalar object.
-
equals–Check if two objects are equal and track the location of differences.
-
list_as_string–Convert a list to a formatted string.
-
pass_none_if_keyerror–Decorate functions to pass None if a KeyError or AttributeError is raised.
-
resample_timeseries–Resample a DataFrame with proper handling of numeric and non-numeric columns.
-
expand_series–Expand a series to a dataframe quickly.
-
generate_colors–Generate a list of colors from a matplotlib palette.
-
annuity–Calculate the annuity factor for a given discount rate and lifetime.
-
normalize_carrier_nice_names–Normalize carrier nice names to carrier names.
pypsa.common.UnexpectedError
¶
UnexpectedError(message: str = '')
Bases: AssertionError
flowchart TD
pypsa.common.UnexpectedError[UnexpectedError]
click pypsa.common.UnexpectedError href "" "pypsa.common.UnexpectedError"
Custom error for unexpected conditions with issue tracker reference.
Parameters:
-
message(str, default:'') –Message to be displayed.
Examples:
>>> try:
... raise UnexpectedError("This is an unexpected error.")
... except UnexpectedError as e:
... print(str(e))
This is an unexpected error.
Please track this issue in our issue tracker: https://go.pypsa.org/report-bug
pypsa.common.as_index
¶
as_index(n: NetworkType, values: Any, network_attribute: str, force_subset: bool = True) -> Index
Return a pd.Index object from a list-like or scalar object.
Also checks if the values are a subset of the corresponding attribute of the network object. If values is None, it is also used as the default.
Parameters:
-
n(Network) –Network object from which to extract the default values.
-
values(Any) –List-like or scalar object or None.
-
network_attribute(str) –Name of the network attribute to be used as the default values. Only used if values is None.
-
force_subset(bool, default:True) –If True, the values must be a subset of the network attribute. Otherwise this is not checked, by default True.
Returns:
-
pd.Index: values as a pd.Index object.–
Examples:
>>> # Convert list to Index using network snapshots
>>> first_two = list(n.snapshots[:2])
>>> pypsa.common.as_index(n, first_two, 'snapshots')
DatetimeIndex([..., ...], dtype='datetime64[ns]', name='snapshot', freq=None)
>>> # Using None returns all snapshots
>>> pypsa.common.as_index(n, None, 'snapshots')
DatetimeIndex([..., ...], dtype='datetime64[ns]', name='snapshot', freq=None)
pypsa.common.equals
¶
equals(a: Any, b: Any, ignored_classes: Any = None, log_mode: str = 'silent', path: str = '') -> bool
Check if two objects are equal and track the location of differences.
Parameters:
-
a(Any) –First object to compare.
-
b(Any) –Second object to compare.
-
ignored_classes(Any, default:None) –Classes to ignore during comparison. If None, no classes are ignored.
-
log_mode(str, default:'silent') –Controls how differences are reported: - 'silent': No logging, just returns True/False - 'verbose': Prints differences but doesn't raise errors - 'strict': Raises ValueError on first difference
-
path(str, default:'') –Current path in the object structure (used for tracking differences).
Raises:
-
ValueError–If log_mode is 'strict' and components are not equal.
Returns:
-
bool–True if the objects are equal, False otherwise.
Examples:
>>> # Compare pandas DataFrames
>>> df1 = pd.DataFrame({'a': [1, 2], 'b': [3, 4]})
>>> df2 = pd.DataFrame({'a': [1, 2], 'b': [3, 4]})
>>> pypsa.common.equals(df1, df2)
True
>>> # Compare lists
>>> pypsa.common.equals([1, 2, 3], [1, 2, 4])
False
>>> # Handle NaN values correctly
>>> pypsa.common.equals(np.nan, np.nan)
True
pypsa.common.list_as_string
¶
list_as_string(list_: Sequence | dict | set, prefix: str = '', style: str = 'comma-separated') -> str
Convert a list to a formatted string.
Parameters:
-
list_(Sequence) –The input sequence to be converted.
-
prefix(str, default:'') –String to prepend to each line, by default "".
-
style(('same-line', 'bullet-list'), default:'same-line') –Output format style, by default "same-line".
Returns:
-
str–Formatted string representation of the input sequence.
Raises:
-
ValueError–If an invalid style is provided.
Examples:
>>> list_as_string(['a', 'b', 'c'])
'a, b, c'
>>> list_as_string(['x', 'y'], prefix=' ')
' x, y'
pypsa.common.pass_none_if_keyerror
¶
pass_none_if_keyerror(func: Callable) -> Callable
Decorate functions to pass None if a KeyError or AttributeError is raised.
Parameters:
-
func(Callable) –The function to decorate.
Returns:
-
Callable–The decorated function.
pypsa.common.resample_timeseries
¶
resample_timeseries(df: DataFrame, freq: str, numeric_columns: list[str] | None = None) -> DataFrame
Resample a DataFrame with proper handling of numeric and non-numeric columns.
Parameters:
-
df(DataFrame) –DataFrame to resample, must have a datetime index
-
freq(str) –Frequency string for resampling (e.g. 'H' for hourly)
-
numeric_columns(list[str] | None, default:None) –List of numeric column names to resample. If None, auto-detected.
Returns:
-
DataFrame–Resampled DataFrame with numeric columns aggregated by mean and non-numeric columns forward-filled
Examples:
>>> # Create time series with mixed data types
>>> dates = pd.date_range('2020-01-01', periods=4, freq='15min')
>>> df = pd.DataFrame({
... 'value': [1.0, 2.0, 3.0, 4.0],
... 'label': ['A', 'A', 'B', 'B']
... }, index=dates)
>>> resampled = pypsa.common.resample_timeseries(df, '30min')
>>> resampled['value'].iloc[0] # Mean of first two values
np.float64(1.5)
>>> resampled['label'].iloc[0] # Forward-filled non-numeric
'A'
pypsa.common.expand_series
¶
expand_series(ser: Series, columns: Sequence[str]) -> DataFrame
Expand a series to a dataframe quickly.
Columns are the given series and every single column being the equal to the given series.
Parameters:
-
ser(Series) –Input series to expand.
-
columns(Sequence[str]) –Column names for the resulting DataFrame.
Returns:
-
DataFrame–DataFrame with all columns containing the same values as the input series.
Examples:
>>> ser = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
>>> df = pypsa.common.expand_series(ser, ['col1', 'col2'])
>>> df
col1 col2
a 1.0 1.0
b 2.0 2.0
c 3.0 3.0
pypsa.common.generate_colors
¶
generate_colors(n_colors: int, palette: str = 'tab10') -> list[str]
Generate a list of colors from a matplotlib palette.
Parameters:
-
n_colors(int) –Number of colors to generate.
-
palette(str, default:"tab10") –Matplotlib color palette name.
Returns:
-
list of str–List of hex color strings.
Examples:
>>> pypsa.common.generate_colors(3, "tab10")
['#1f77b4', '#ff7f0e', '#2ca02c']
pypsa.common.annuity
¶
annuity(r: float | Series, n: int | Series) -> float | Series
Calculate the annuity factor for a given discount rate and lifetime.
Deprecated since 1.1.0: Use pypsa.costs.annuity() instead.
According to formula \(r / (1 - (1 + r)^{-n})\) or \(1 / n\) for \(r = 0\).
Parameters:
-
r(float | Series) –Discount rate (as a decimal, e.g. 0.05 for 5%).
-
n(int | Series) –Lifetime of loan or asset (in years).
Returns:
-
float | Series–The annuity factor.
- Home Overview Release Notes v1.0.0 14th October 2025 🎉 Features
pypsa.common.normalize_carrier_nice_names
¶
normalize_carrier_nice_names(nice_name_series: Series, carrier: str | Sequence[str] | None) -> str | Sequence[str] | None
Normalize carrier nice names to carrier names.
Parameters:
-
nice_name_series(Series) –Series with carrier names as index and nice names as values (i.e.
n.c.carriers.static.nice_name). -
carrier(str | Sequence[str] | None) –Carrier name(s) to normalize.
Returns:
-
str | Sequence[str] | None–Normalized carrier name(s).
geo
¶
Functionality to help with georeferencing and calculate distances/areas.
Functions:
-
compute_bbox–Compute bounding box for given x, y coordinates.
-
get_projected_area_factor–Get scale of current vs original projection in terms of area.
-
get_projection_from_crs–Get cartopy projection from EPSG code or proj4 string.
-
haversine–Compute the distance in km between two sets of points in long/lat.
-
haversine_pts–Determine crow-flies distance between points in a and b.
pypsa.geo.compute_bbox
¶
compute_bbox(x: ArrayLike, y: ArrayLike, margin: float = 0) -> tuple[tuple[float, float], tuple[float, float]]
Compute bounding box for given x, y coordinates.
Also adds a margin around the bounding box, if desired. Defaults to 0.
Parameters:
-
x(array - like) –Arrays of x and y coordinates
-
y(array - like) –Arrays of x and y coordinates
-
margin(float, default:0) –Margin around the bounding box, by default 0
Returns:
-
tuple–Tuple of two tuples, representing the lower left (x1, y1) and upper right (x2, y2) corners of the bounding box
Examples:
>>> x = np.array([1, 2, 3])
>>> y = np.array([4, 5, 6])
>>> compute_bbox(x, y)
((np.int64(1), np.int64(4)), (np.int64(3), np.int64(6)))
>>> # With margin to expand the bounding box
>>> compute_bbox(x, y, margin=0.1)
((..., ...), (..., ...))
pypsa.geo.get_projected_area_factor
¶
get_projected_area_factor(ax: GeoAxes, original_crs: int | str = DEFAULT_EPSG) -> float
Get scale of current vs original projection in terms of area.
The default 'original crs' is assumed to be 4326, which translates to the cartopy default cartopy.crs.PlateCarree()
Examples:
>>> import cartopy.crs as ccrs
>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots(subplot_kw={"projection": ccrs.Mercator()})
>>> ax.set_extent([-10, 10, 40, 60], crs=ccrs.PlateCarree())
>>> area_factor = get_projected_area_factor(ax)
>>> area_factor
np.float64(140056.26937534288)
pypsa.geo.get_projection_from_crs
¶
get_projection_from_crs(crs: int | str) -> Projection
Get cartopy projection from EPSG code or proj4 string.
If the projection is not found, a warning is issued and the default PlateCarree projection is returned.
Parameters:
-
crs(int | str) –EPSG code or proj4 string
Returns:
-
projection(Projection) –Cartopy projection object
Examples:
>>> get_projection_from_crs(4326)
<Projected CRS: +proj=eqc +ellps=WGS84 +a=6378137.0 +lon_0=0.0 +to ...>
Name: unknown
Axis Info [cartesian]:
- E[east]: Easting (unknown)
- N[north]: Northing (unknown)
- h[up]: Ellipsoidal height (metre)
Area of Use:
- undefined
Coordinate Operation:
- name: unknown
- method: Equidistant Cylindrical
Datum: Unknown based on WGS 84 ellipsoid
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich
pypsa.geo.haversine
¶
haversine(a: ArrayLike, b: ArrayLike) -> ndarray
Compute the distance in km between two sets of points in long/lat.
One dimension of a* should be 2; longitude then latitude. Uses haversine formula.
Parameters:
-
a(N x 2 - array of dtype float) –Coordinates of first point, dimensions (N, 2)
-
b(array-like of at most 2 dimensions) –Coordinates of second point, dimensions (M, 2)
Returns:
-
distance_km(array) –2-dimensional array of distances in km between points in a, b
Examples:
>>> haversine([10.1, 52.6], [[10.8, 52.1], [-34, 56.]])
array([[ 73.15416698, 2836.6707696 ]])
-
API Reference
Components
Component Types
Line
Linescalculate_line_length
pypsa.geo.haversine_pts
¶
haversine_pts(a: ArrayLike, b: ArrayLike) -> ndarray
Determine crow-flies distance between points in a and b.
ie. distance[i] = crow-fly-distance between a[i] and b[i]
Parameters:
-
a(N x 2 - array of dtype float) –Geographical coordinates in longitude, latitude ordering
-
b(N x 2 - array of dtype float) –Geographical coordinates in longitude, latitude ordering
Returns:
-
c(N - array of dtype float) –Distance in km
Examples:
>>> a = np.array([[10.1, 52.6], [10.8, 52.1]])
>>> b = np.array([[10.8, 52.1], [-34, 56.]])
>>> haversine_pts(a, b)
array([ 73.15416698, 2903.73511621])