예제 #1
0
 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)
예제 #2
0
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
예제 #3
0
def test_dimension():
    # Constructor
    Dimension(id='CURRENCY', order=0)