Unit conversion¶
Each column of a Table has a unit attribute. Pdtable provides a framework to convert a table’s values to a different set of units.
To convert units on a Table, you have to specify two things:
What units you want to convert to; and
A unit converter describing how to do the conversion from the existing units to the new units.
This unit converter is a Callable of your choice with this signature:
def some_converter(value, from_unit, to_unit):
# convert value
...
return converted_value
For convenience, pdtable ships with a Pint-based unit converter that you
can use as-is or inherit from and configure at will. pint is an
optional dependency; it doesn’t need to be installed unless and until you use the
Pint-based converter.
Consider this example table:
t = Table(name="places")
t.add_column("where", ["home", "work", "beach"], unit="text")
t.add_column("distance", [0, 14, 18], unit="km")
t["is_hot"] = [False, False, True]
t["ETA"] = [datetime(2020, 11, 2), pd.to_datetime("2020-11-02 9:00:00"), datetime(2020, 11, 7)]
t["ETA"].unit = 'datetime'
t.df.loc[len(t.df)] = ["unicornland", np.nan, False, pd.NaT]
t
**places all where [text] distance [km] is_hot [onoff] ETA [datetime] 0 home 0.0 False 2020-11-02 00:00:00 1 work 14.0 False 2020-11-02 09:00:00 2 beach 18.0 True 2020-11-07 00:00:00 3 unicornland NaN False NaT
Here’s an example where we explicitly specify which columns to convert to what unit, using the bundled pint-based unit converter. In this example, we only ask to convert a single column.
t.convert_units(to={"distance": "lightyear"},
converter=pdtable.pint_converter)
**places all where [text] distance [lightyear] is_hot [onoff] ETA [datetime] 0 home 0.000000e+00 False 2020-11-02 00:00:00 1 work 1.479801e-12 False 2020-11-02 09:00:00 2 beach 1.902602e-12 True 2020-11-07 00:00:00 3 unicornland NaN False NaT
If your converter implements the concept of “base unit” then you can bulk convert all columns to their base units with to='base'. The built-in pint-based converted does support this. For instance, the base unit of “km” is “meter”.
t.convert_units(to="base", converter=pdtable.pint_converter)
**places all where [text] distance [meter] is_hot [onoff] ETA [datetime] 0 home 0.0 False 2020-11-02 00:00:00 1 work 14000.0 False 2020-11-02 09:00:00 2 beach 18000.0 True 2020-11-07 00:00:00 3 unicornland NaN False NaT
Specifying which converter to use every single time can get tedious. You can set a default converter once and for all:
pdtable.units.default_converter = pdtable.pint_converter
t.convert_units(to="base")
**places all where [text] distance [meter] is_hot [onoff] ETA [datetime] 0 home 0.0 False 2020-11-02 00:00:00 1 work 14000.0 False 2020-11-02 09:00:00 2 beach 18000.0 True 2020-11-07 00:00:00 3 unicornland NaN False NaT