Ejemplo n.º 1
0
    def __init__(self,
                 wrapper,
                 mapped_arr,
                 col_arr,
                 id_arr=None,
                 idx_arr=None,
                 value_map=None,
                 **kwargs):
        Wrapping.__init__(self,
                          wrapper,
                          mapped_arr=mapped_arr,
                          col_arr=col_arr,
                          id_arr=id_arr,
                          idx_arr=idx_arr,
                          value_map=value_map,
                          **kwargs)
        mapped_arr = np.asarray(mapped_arr)
        col_arr = np.asarray(col_arr)
        checks.assert_shape_equal(mapped_arr, col_arr, axis=0)
        if id_arr is None:
            id_arr = np.arange(len(mapped_arr))
        if idx_arr is not None:
            idx_arr = np.asarray(idx_arr)
            checks.assert_shape_equal(mapped_arr, idx_arr, axis=0)
        if value_map is not None:
            if checks.is_namedtuple(value_map):
                value_map = to_value_map(value_map)

        self._mapped_arr = mapped_arr
        self._id_arr = id_arr
        self._col_arr = col_arr
        self._idx_arr = idx_arr
        self._value_map = value_map
        self._col_mapper = ColumnMapper(wrapper, col_arr)
Ejemplo n.º 2
0
 def value_counts(self, group_by=None, value_map=None, wrap_kwargs=None):
     """Return a pandas object containing counts of unique values."""
     mapped_codes, mapped_uniques = pd.factorize(self.values)
     col_map = self.col_mapper.get_col_map(group_by=group_by)
     value_counts = nb.mapped_value_counts_nb(mapped_codes, col_map)
     value_counts_df = self.wrapper.wrap(value_counts,
                                         index=mapped_uniques,
                                         group_by=group_by,
                                         **merge_dicts({}, wrap_kwargs))
     if value_map is None:
         value_map = self.value_map
     if value_map is not None:
         if checks.is_namedtuple(value_map):
             value_map = to_value_map(value_map)
         value_counts_df.index = value_counts_df.index.map(value_map)
     return value_counts_df
Ejemplo n.º 3
0
 def value_counts(self,
                  group_by: tp.GroupByLike = None,
                  value_map: tp.Optional[tp.ValueMapLike] = None,
                  wrap_kwargs: tp.KwargsLike = None) -> tp.SeriesFrame:
     """Return a pandas object containing counts of unique values."""
     mapped_codes, mapped_uniques = pd.factorize(self.values)
     col_map = self.col_mapper.get_col_map(group_by=group_by)
     value_counts = nb.mapped_value_counts_nb(mapped_codes, col_map)
     value_counts_df = self.wrapper.wrap(value_counts,
                                         index=mapped_uniques,
                                         group_by=group_by,
                                         **merge_dicts({}, wrap_kwargs))
     if value_map is None:
         value_map = self.value_map
     if value_map is not None:
         if checks.is_namedtuple(value_map):
             value_map = to_value_map(value_map)
         value_counts_df.index = value_counts_df.index.map(value_map)
     return value_counts_df
Ejemplo n.º 4
0
def to_mapping(mapping_like: tp.MappingLike, reverse: bool = False) -> dict:
    """Convert mapping-like object to a mapping.

    Enable `reverse` to apply `reverse_mapping` on the result dict."""
    if checks.is_namedtuple(mapping_like):
        mapping = {v: k for k, v in mapping_like._asdict().items()}
        if -1 not in mapping_like:
            mapping[-1] = None
    elif not checks.is_mapping(mapping_like):
        if checks.is_index(mapping_like):
            mapping_like = mapping_like.to_series().reset_index(drop=True)
        if checks.is_series(mapping_like):
            mapping = mapping_like.to_dict()
        else:
            mapping = dict(enumerate(mapping_like))
    else:
        mapping = dict(mapping_like)
    if reverse:
        mapping = reverse_mapping(mapping)
    return mapping
Ejemplo n.º 5
0
def deep_substitute(obj: tp.Any,
                    mapping: tp.Optional[tp.Mapping] = None) -> tp.Any:
    """Traverses an object recursively and substitutes all templates using a mapping.

    Traverses tuples, lists, dicts and (frozen-)sets. Does not look for templates in keys.

    ## Example

    ```python-repl
    >>> from vectorbt.utils.template import Rep, Sub, deep_substitute

    >>> deep_substitute(Rep('key'), {'key': 100})
    100
    >>> deep_substitute(Sub('$key$key'), {'key': 100})
    '100100'
    >>> deep_substitute([Rep('key'), Sub('$key$key')], {'key': 100})
    [100, '100100']
    ```"""
    if mapping is None:
        mapping = {}
    if isinstance(obj, Rep):
        return mapping[obj.template]
    if isinstance(obj, Template):
        return obj.substitute(mapping)
    if isinstance(obj, dict):
        obj = copy(obj)
        for k, v in obj.items():
            set_dict_item(obj,
                          k,
                          deep_substitute(v, mapping=mapping),
                          force=True)
        return obj
    if isinstance(obj, (tuple, list, set, frozenset)):
        result = []
        for o in obj:
            result.append(deep_substitute(o, mapping=mapping))
        if checks.is_namedtuple(obj):
            return type(obj)(*result)
        return type(obj)(result)
    return obj
Ejemplo n.º 6
0
def deep_substitute(obj: tp.Any,
                    mapping: tp.Optional[tp.Mapping] = None,
                    safe: bool = False,
                    make_copy: bool = True) -> tp.Any:
    """Traverses the object recursively and, if any template found, substitutes it using a mapping.

    Traverses tuples, lists, dicts and (frozen-)sets. Does not look for templates in keys.

    If `safe` is True, won't raise an error but return the original template.

    !!! note
        If the object is deep (such as a dict or a list), creates a copy of it if any template found inside,
        thus loosing the reference to the original. Make sure to do a deep or hybrid copy of the object
        before proceeding for consistent behavior, or disable `make_copy` to override the original in place.

    Usage:
        ```pycon
        >>> import vectorbt as vbt

        >>> vbt.deep_substitute(vbt.Sub('$key', {'key': 100}))
        100
        >>> vbt.deep_substitute(vbt.Sub('$key', {'key': 100}), {'key': 200})
        200
        >>> vbt.deep_substitute(vbt.Sub('$key$key'), {'key': 100})
        100100
        >>> vbt.deep_substitute(vbt.Rep('key'), {'key': 100})
        100
        >>> vbt.deep_substitute([vbt.Rep('key'), vbt.Sub('$key$key')], {'key': 100})
        [100, '100100']
        >>> vbt.deep_substitute(vbt.RepFunc(lambda key: key == 100), {'key': 100})
        True
        >>> vbt.deep_substitute(vbt.RepEval('key == 100'), {'key': 100})
        True
        >>> vbt.deep_substitute(vbt.RepEval('key == 100', safe=False))
        NameError: name 'key' is not defined
        >>> vbt.deep_substitute(vbt.RepEval('key == 100', safe=True))
        <vectorbt.utils.template.RepEval at 0x7fe3ad2ab668>
        ```
    """
    if mapping is None:
        mapping = {}
    if not has_templates(obj):
        return obj
    try:
        if isinstance(obj, RepFunc):
            return obj.call(mapping)
        if isinstance(obj, RepEval):
            return obj.eval(mapping)
        if isinstance(obj, Rep):
            return obj.replace(mapping)
        if isinstance(obj, Sub):
            return obj.substitute(mapping)
        if isinstance(obj, Template):
            return obj.substitute(mapping)
        if isinstance(obj, dict):
            if make_copy:
                obj = copy(obj)
            for k, v in obj.items():
                set_dict_item(obj, k, deep_substitute(v, mapping=mapping, safe=safe), force=True)
            return obj
        if isinstance(obj, list):
            if make_copy:
                obj = copy(obj)
            for i in range(len(obj)):
                obj[i] = deep_substitute(obj[i], mapping=mapping, safe=safe)
            return obj
        if isinstance(obj, (tuple, set, frozenset)):
            result = []
            for o in obj:
                result.append(deep_substitute(o, mapping=mapping, safe=safe))
            if checks.is_namedtuple(obj):
                return type(obj)(*result)
            return type(obj)(result)
    except Exception as e:
        if not safe:
            raise e
    return obj