From e5d6e1d2fdda5ae8c4cfe9d8e4c364f25b2c531b Mon Sep 17 00:00:00 2001 From: Théo de la Hogue Date: Wed, 16 Nov 2022 15:49:58 +0100 Subject: Replacing get_first and get_last method by first and last properties. Improving notes and warning. Properly ordering splited columns in dataframe. --- src/argaze/DataStructures.py | 75 ++++++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 23 deletions(-) diff --git a/src/argaze/DataStructures.py b/src/argaze/DataStructures.py index 0c1dd5e..9339227 100644 --- a/src/argaze/DataStructures.py +++ b/src/argaze/DataStructures.py @@ -28,11 +28,10 @@ class TimeStampedBuffer(collections.OrderedDict): } ``` - .. warning:: - Timestamps must be numbers. + .. warning:: Timestamps must be numbers. - .. warning:: - Timestamps are not sorted by any order. + .. warning:: Timestamps are not sorted internally. + Data are considered to be stored according at their coming time. """ def __new__(cls, args = None): @@ -60,7 +59,8 @@ class TimeStampedBuffer(collections.OrderedDict): return self - def get_first(self) -> Tuple[TimeStampType, DataType]: + @property + def first(self) -> Tuple[TimeStampType, DataType]: """Easing access to first item.""" return list(self.items())[0] @@ -73,7 +73,7 @@ class TimeStampedBuffer(collections.OrderedDict): def pop_first_until(self, ts: TimeStampType) -> Tuple[TimeStampType, DataType]: """Pop all item until a given timestamped value and return the last poped item.""" - # get last timestamp before given timestamp + # get last item before given timestamp earliest_ts, earliest_value = self.get_last_before(ts) popep_ts, poped_value = self.pop_first() @@ -83,7 +83,8 @@ class TimeStampedBuffer(collections.OrderedDict): return popep_ts, poped_value - def get_last(self) -> Tuple[TimeStampType, DataType]: + @property + def last(self) -> Tuple[TimeStampType, DataType]: """Easing access to last item.""" return list(self.items())[-1] @@ -109,33 +110,51 @@ class TimeStampedBuffer(collections.OrderedDict): raise KeyError(f'No data stored before {ts} timestamp.') - def export_as_json(self, filepath): - """Write buffer content into a json file.""" - - try: - with open(filepath, 'w', encoding='utf-8') as jsonfile: - json.dump(self, jsonfile, ensure_ascii = False, default=vars) + def as_dataframe(self, exclude=[], split={}) -> pandas.DataFrame: + """Convert as [pandas dataframe](https://pandas.pydata.org/docs/reference/frame.html). + + The optional *split* argument allows tuple values to be stored in a dedicated columns. + For example: to convert {"point": (0, 0)} data as two separated "x" and "y" columns, use split={"point":["x", "y"]} - except: - raise RuntimeError(f'Can\' write {filepath}') + .. warning:: Values must be dictionaries. + Each key is stored as a column name. - def as_dataframe(self, exclude=[], split={}) -> pandas.DataFrame: - """Convert buffer as pandas dataframe. Timestamped values must be stored as dictionary where each keys will be related to a column.""" + .. note:: Timestamps are stored as index column called 'timestamp'. + """ df = pandas.DataFrame.from_dict(self.values()) + + # Exclude columns df.drop(exclude, inplace=True, axis=True) - for key, columns in split.items(): - df[columns] = pandas.DataFrame(df[key].tolist(), index=df.index) - df.drop(key, inplace=True, axis=True) + # Split columns + splited_columns = [] + for column in df.columns: + + if column in split.keys(): + + df[split[column]] = pandas.DataFrame(df[column].tolist(), index=df.index) + df.drop(column, inplace=True, axis=True) + + for new_column in split[column]: + splited_columns.append(new_column) + + else: + + splited_columns.append(column) + + # Reorder splited columns + df = df[splited_columns] + + # Append timestamps as index column df['timestamp'] = self.keys() df.set_index('timestamp', inplace=True) return df - def export_as_csv(self, filepath, exclude=[]): - """Write buffer content into a csv file.""" + def save_as_csv(self, filepath, exclude=[]): + """Write into a csv file.""" try: self.as_dataframe(exclude=exclude).to_csv(filepath, index=True) @@ -143,8 +162,18 @@ class TimeStampedBuffer(collections.OrderedDict): except: raise RuntimeError(f'Can\' write {filepath}') + def save_as_json(self, filepath): + """Write into a json file.""" + + try: + with open(filepath, 'w', encoding='utf-8') as jsonfile: + json.dump(self, jsonfile, ensure_ascii = False, default=vars) + + except: + raise RuntimeError(f'Can\' write {filepath}') + def plot(self, names=[], colors=[], split={}, samples=None) -> list: - """Plot data into time chart.""" + """Plot as [matplotlib](https://matplotlib.org/) time chart.""" df = self.as_dataframe(split=split) legend_patches = [] -- cgit v1.1