Source code for larray.core.metadata
from typing import List, Optional
class AttributeDict(dict):
def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError(key)
def __setattr__(self, key, value):
self[key] = value
def __delattr__(self, key):
del self[key]
def __dir__(self) -> List[str]:
return list(set(super().__dir__()) | set(self.keys()))
def __repr__(self) -> str:
return '\n'.join([f'{k}: {v}' for k, v in self.items()])
[docs]
class Metadata(AttributeDict):
r"""
An ordered dictionary allowing key-values accessibly using attribute notation (AttributeDict.attribute)
instead of key notation (Dict["key"]).
Examples
--------
>>> from larray import ndtest
>>> from datetime import datetime
Add metadata at array initialization
>>> arr = ndtest((3, 3), meta=Metadata(title='the title', author='John Smith'))
Add metadata after array initialization
>>> arr.meta.creation_date = datetime(2017, 2, 10)
Access to metadata
>>> arr.meta.creation_date
datetime.datetime(2017, 2, 10, 0, 0)
Modify metadata
>>> arr.meta.creation_date = datetime(2017, 2, 16)
Delete metadata
>>> del arr.meta.creation_date
"""
def __larray__(self):
from larray.core.array import stack
return stack(self.items(), axes='metadata')
@classmethod
def from_array(cls, array) -> 'Metadata':
from larray.core.array import asarray
array = asarray(array)
if array.ndim != 1:
raise ValueError(f"Expected Array object of dimension 1. Got array of dimension {array.ndim}")
from pandas import to_numeric, to_datetime
def _convert_value(value):
# first try converting to a number ...
try:
value = to_numeric(value)
except (ValueError, TypeError):
# ... if that failed try converting to a datetime ...
try:
value = to_datetime(value)
except (ValueError, TypeError):
# ... and if that failed too, keep the original value (probably a string)
pass
return value
return Metadata({key: _convert_value(value) for key, value in zip(array.axes[0].labels, array.data)})
# ---------- IO methods ----------
def to_hdf(self, hdfstore, key=None):
if len(self):
attrs = hdfstore.get_storer(key).attrs if key is not None else hdfstore.root._v_attrs
attrs.metadata = self
@classmethod
def from_hdf(cls, hdfstore, key=None) -> Optional['Metadata']:
attrs = hdfstore.get_storer(key).attrs if key is not None else hdfstore.root._v_attrs
if 'metadata' in attrs:
return attrs.metadata
else:
return None