From 84d88caf3e0a3c8b5656f88495265573e43fa749 Mon Sep 17 00:00:00 2001 From: Wolfgang Kerzendorf Date: Mon, 24 Jan 2022 22:56:45 +0100 Subject: [PATCH] first commit for QDataFrame --- pandas/util/qdataframe.py | 82 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 pandas/util/qdataframe.py diff --git a/pandas/util/qdataframe.py b/pandas/util/qdataframe.py new file mode 100644 index 0000000000000..15c2eb624ca1b --- /dev/null +++ b/pandas/util/qdataframe.py @@ -0,0 +1,82 @@ +import pandas as pd +import numpy as np +from astropy import units as u + +class QSeries(pd.Series): + + _metadata = ["unit"] + + def __init__(self, *args, unit=None, **kwargs): + super().__init__(*args, **kwargs) + self.unit = unit + + @property + def _constructor(self): + return QSeries + + @property + def _constructor_expanddim(self): + return QDataFrame + + def to(self, unit): + transformed_values = self.values * self.unit.to(unit) + return QSeries(data=transformed_values, unit=unit) + +class QDataFrame(pd.DataFrame): + # normal properties + _metadata = ["units"] + + def __init__(self, *args, units=None, **kwargs): + super().__init__(*args, **kwargs) + self.units = units + + @property + def units(self): + return {column:self[column].unit + for column in self.columns + if hasattr(self[column], 'unit')} + + @units.setter + def units(self, new_units): + + if new_units is None: + return + for column in self.columns: + if column in new_units: + self[column].unit = new_units[column] + + @property + def _constructor(self): + return QDataFrame + + @property + def _constructor_sliced(self): + return QSeries + + def __finalize__(self, other, method=None, **kwargs): + """ + Code taken from: https://github.com/geopandas/geopandas/blob/master/geopandas/geodataframe.py + """ + super().__finalize__(other, method=method, **kwargs) + if hasattr(other, 'units'): + self.units = other.units + + # merge operation: using metadata of the left object + if method == "merge": + for name in self._metadata: + object.__setattr__(self, name, getattr(other.left, name, None)) + # concat operation: using metadata of the first object + elif method == "concat": + for name in self._metadata: + object.__setattr__(self, name, getattr(other.objs[0], name, None)) + + return self + + def _repr_html_(self) -> str: + repr_html = super()._repr_html_() + for col_name, col_unit in self.units.items(): + if col_unit is None: + continue + col_unit_latex = col_unit.to_string('latex') + repr_html = repr_html.replace(f'{col_name}', f'{col_name} [ {col_unit_latex} ]') + return repr_html \ No newline at end of file