def _set_obs_dim(self, value): """Store the observation dimension for the current DataSet.""" if value == 'AllDimensions': self._obs_dim = AllDimensions else: try: # Retrieve an already-defined Dimension (e.g. from the DSD) obs_dim = self._index[('Dimension', value)] except KeyError: obs_dim = Dimension(id=value) self._obs_dim = wrap(obs_dim)
def _maybe_convert_datetime(df, arg, obj, dsd=None): """Helper for :meth:`.write_dataset` to handle datetime indices. Parameters ---------- df : pandas.DataFrame arg : dict From the `datetime` argument to :meth:`write_dataset`. obj : From the `obj` argument to :meth:`write_dataset`. dsd: ~.DataStructureDefinition, optional """ if not arg: # False, None, empty dict: no datetime conversion return df # Check argument values param = dict(dim=None, axis=0, freq=False) if isinstance(arg, str): param['dim'] = arg elif isinstance(arg, DimensionComponent): param['dim'] = arg.id elif isinstance(arg, dict): extra_keys = set(arg.keys()) - set(param.keys()) if extra_keys: raise ValueError(extra_keys) param.update(arg) elif isinstance(arg, bool): pass # True else: raise ValueError(arg) def _get_dims(): """Return an appropriate list of dimensions.""" if len(obj.structured_by.dimensions.components): return obj.structured_by.dimensions.components elif dsd: return dsd.dimensions.components else: return [] def _get_attrs(): """Return an appropriate list of attributes.""" if len(obj.structured_by.attributes.components): return obj.structured_by.attributes.components elif dsd: return dsd.attributes.components else: return [] if not param['dim']: # Determine time dimension dims = _get_dims() for dim in dims: if isinstance(dim, TimeDimension): param['dim'] = dim break if not param['dim']: raise ValueError(f'no TimeDimension in {dims}') # Unstack all but the time dimension and convert other_dims = list(filter(lambda d: d != param['dim'], df.index.names)) df = df.unstack(other_dims) df.index = pd.to_datetime(df.index) if param['freq']: # Determine frequency string, Dimension, or Attribute freq = param['freq'] if isinstance(freq, str) and freq not in pd.offsets.prefix_mapping: # ID of a Dimension or Attribute for component in chain(_get_dims(), _get_attrs()): if component.id == freq: freq = component break # No named dimension in the DSD; but perhaps on the df if isinstance(freq, str): if freq in df.columns.names: freq = Dimension(id=freq) else: raise ValueError(freq) if isinstance(freq, Dimension): # Retrieve Dimension values from pd.MultiIndex level level = freq.id i = df.columns.names.index(level) values = set(df.columns.levels[i]) if len(values) > 1: values = sorted(values) raise ValueError('cannot convert to PeriodIndex with ' f'non-unique freq={values}') # Store the unique value freq = values.pop() # Remove the index level df.columns = df.columns.droplevel(i) elif isinstance(freq, DataAttribute): # pragma: no cover raise NotImplementedError df.index = df.index.to_period(freq=freq) if param['axis'] in {1, 'columns'}: # Change axis df = df.transpose() return df
def test_dimension(): # Constructor Dimension(id='CURRENCY', order=0)