1414from pandas_openscm .indexing import multi_index_match
1515
1616if TYPE_CHECKING :
17- import pint
17+ import pint . facets
1818
1919
2020def convert_unit_from_target_series (
2121 df : pd .DataFrame ,
2222 desired_unit : pd .Series [str ],
2323 unit_level : str = "unit" ,
24- ur : pint .UnitRegistry | None = None ,
24+ ur : pint .facets . PlainRegistry | None = None ,
2525) -> pd .DataFrame :
26+ """
27+ Convert `df`'s units based on a [pd.Series][pandas.Series]
28+
29+ `desired_uni` defines the units to convert to.
30+ This is a relatively low-level function,
31+ you may find [convert_unit][] and [convert_unit_like][] easier to use.
32+
33+ Parameters
34+ ----------
35+ df
36+ [pd.DataFrame][pandas.DataFrame] whose units should be converted
37+
38+ desired_unit
39+ Desired unit(s) for `df`
40+
41+ This must be a [pd.Series][pandas.Series]
42+ with an index that contains all the rows in `df`.
43+
44+ unit_level
45+ Level in `df` which holds unit information
46+
47+ ur
48+ Unit registry to use for the conversion.
49+
50+ If not supplied, we use [pint.get_application_registry][].
51+
52+ Returns
53+ -------
54+ :
55+ `df` with converted units
56+
57+ Raises
58+ ------
59+ AssertionError
60+ `desired_unit`'s index does not contain all the rows in `df`
61+
62+ MissingOptionalDependencyError
63+ `ur` is `None` and [pint](https://pint.readthedocs.io/) is not available.
64+
65+ Examples
66+ --------
67+ >>> import pandas as pd
68+ >>>
69+ >>> start = pd.DataFrame(
70+ ... [[1.0, 2.0, 3.0], [1.1, 1.2, 1.3], [37.0, 38.1, 37.9]],
71+ ... columns=[2020, 2030, 2050],
72+ ... index=pd.MultiIndex.from_tuples(
73+ ... (
74+ ... ("sa", "temperature", "mK"),
75+ ... ("sb", "temperature", "K"),
76+ ... ("sb", "body temperature", "degC"),
77+ ... ),
78+ ... names=["scenario", "variable", "unit"],
79+ ... ),
80+ ... )
81+ >>>
82+ >>> convert_unit_from_target_series(
83+ ... start,
84+ ... desired_unit=pd.Series(
85+ ... ["K", "mK", "degF"],
86+ ... index=pd.MultiIndex.from_tuples(
87+ ... (
88+ ... ("sa", "temperature"),
89+ ... ("sb", "temperature"),
90+ ... ("sb", "body temperature"),
91+ ... ),
92+ ... names=["scenario", "variable"],
93+ ... ),
94+ ... ),
95+ ... )
96+ 2020 2030 2050
97+ scenario variable unit
98+ sa temperature K 0.001 0.002 0.003
99+ sb temperature mK 1100.000 1200.000 1300.000
100+ body temperature degF 98.600 100.580 100.220
101+ """
26102 missing_rows = df .index .difference (desired_unit .index )
27103 if not missing_rows .empty :
28- msg = "Missing desired unit for {missing_rows}"
104+ msg = f "Missing desired unit for { missing_rows } "
29105 raise AssertionError (msg )
30106
31107 df_reset_unit = df .reset_index (unit_level )
@@ -55,9 +131,6 @@ def convert_unit_from_target_series(
55131 for (df_unit , target_unit ), conversion_df in unit_map [~ unit_map_no_change ].groupby (
56132 ["df_unit" , "target_unit" ]
57133 ):
58- if df_unit == target_unit :
59- continue
60-
61134 to_alter_loc = multi_index_match (df_no_unit .index , conversion_df .index ) # type: ignore
62135 df_no_unit .loc [to_alter_loc , :] = (
63136 ur .Quantity (df_no_unit .loc [to_alter_loc , :].values , df_unit )
@@ -80,7 +153,7 @@ def convert_unit(
80153 df : pd .DataFrame ,
81154 desired_unit : str | Mapping [str , str ] | pd .Series [str ],
82155 unit_level : str = "unit" ,
83- ur : pint .UnitRegistry | None = None ,
156+ ur : pint .facets . PlainRegistry | None = None ,
84157) -> pd .DataFrame :
85158 """
86159 Convert a [pd.DataFrame][pandas.DataFrame]'s units
0 commit comments