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)
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
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
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
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
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