def test_add_multi_index(self): df = pd.DataFrame({}, index=[1, 2, 3, 4]) df1 = add_multi_index(df, "A", axis=0) df2 = add_multi_index(df1, "B", axis=0, level=1) df3 = add_multi_index(df1, "B", axis=0, level=2) # print(df3) self.assertListEqual(df1.index.to_list(), [("A", 1), ("A", 2), ("A", 3), ("A", 4)]) self.assertListEqual(df2.index.to_list(), [("A", "B", 1), ("A", "B", 2), ("A", "B", 3), ("A", "B", 4)]) self.assertListEqual(df3.index.to_list(), [(1, "A", "B"), (2, "A", "B"), (3, "A", "B"), (4, "A", "B")])
def fetch_timeseries(providers: Dict[Callable[[Any], pd.DataFrame], List[str]], start_date: str = None, force_lower_case: bool = False, multi_index: bool = None, ffill: bool = False, **kwargs): symbol_type = (List, Tuple, Set) expected_frames = sum( len(s) if isinstance(s, symbol_type) else 1 for s in providers.values()) df = None if multi_index is None and expected_frames > 1: multi_index = True for provider, symbols in providers.items(): # make sure provider is an actual provider -> a callable if not callable(provider): provider = PROVIDER_MAP[provider] # make sure the symbols are iterable -> wrap single symbols into a list if not isinstance(symbols, symbol_type): symbols = [symbols] # fetch all symbols of all providers (later we could do this in parallel) for symbol in symbols: _df = call_callable_dynamic_args(provider, symbol, multi_index=multi_index, **kwargs) if _df is None: continue if multi_index: if not isinstance(_df.columns, pd.MultiIndex): _df = add_multi_index(_df, symbol, True) if force_lower_case: _df.columns = pd.MultiIndex.from_tuples([ (h.lower(), c.lower()) for h, c in _df.columns.to_list() ]) else: if isinstance(_df.columns, pd.MultiIndex): _df.columns = [t[-1] for t in _df.columns.to_list()] if force_lower_case: _df.columns = [c.lower() for c in _df.columns.to_list()] if df is None: df = _df else: df = inner_join(df, _df, force_multi_index=multi_index, ffill=ffill) return df if start_date is None else df[start_date:]
def ta_multi_ma(df: _t.PatchedDataFrame, average_function='sma', period=12, factors=_np.linspace(1 - 0.2, 1 + 0.2, 5)) -> _t.PatchedDataFrame: ma = {'sma': ta_sma, 'ema': ta_ema, 'wilder': ta_wilders} res = _pd.DataFrame({}, index=df.index) if df.ndim > 1: res = None for col in df.columns.to_list(): _df = ta_multi_ma(df[col], average_function, period, factors) _df = add_multi_index(_df, col) res = inner_join(res, _df, force_multi_index=True) return res for x in factors: res[f"{df.name}_{average_function}({period})({x:.3f})"] = ma[average_function](df, period) * x return res
def fetch_fred(symbols, multi_index=False): if "FRED_API_KEY" not in os.environ: raise ValueError( "you need to set the environment variable `FRED_API_KEY`. You can get a key as described here:" "https://github.com/mortada/fredapi") fred = Fred() df = None if not isinstance(symbols, (List, Tuple, Iterator)): symbols = [symbols] for symbol in symbols: series = fred.get_series(symbol) if not series.name: series.name = symbol if df is None: df = series.to_frame() else: df = df.join(series) return add_multi_index(df, "FRED", True) if multi_index else df
def as_joined_frame(self): frame = pd.concat([add_multi_index(flatten_multi_column_index(f, as_string=True), i) for i, f in enumerate(self._frames)], axis=1, join='outer') frame.columns = frame.columns.to_list() return frame
np.nans = np_nans setattr(PandasObject, "_", property(lambda self: MLCompatibleValues(self))) setattr(PandasObject, "inner_join", inner_join) setattr( PandasObject, "has_multi_index_columns", lambda self: isinstance( self, pd.DataFrame) and isinstance(self.columns, pd.MultiIndex)) setattr(PandasObject, "has_multi_index_rows", lambda self: isinstance(self.index, pd.MultiIndex)) setattr(pd.DataFrame, "to_frame", lambda self: self) setattr(pd.DataFrame, "flatten_columns", flatten_multi_column_index) setattr(pd.DataFrame, "unique_level_columns", unique_level_columns) setattr(pd.DataFrame, "has_indexed_columns", lambda self: has_indexed_columns(self)) setattr(pd.DataFrame, "add_multi_index", lambda self, *args, **kwargs: add_multi_index(self, *args, **kwargs)) setattr(pd.Series, "add_multi_index", lambda self, *args, **kwargs: add_multi_index(self, *args, **kwargs)) setattr(pd.MultiIndex, "unique_level", lambda self, *args: unique_level(self, *args)) class Typing(object): PatchedDataFrame = pd.DataFrame PatchedSeries = pd.Series PatchedPandas = Union[PatchedDataFrame, PatchedSeries] AnyPandasObject = PandasObject DataFrame = pd.DataFrame Series = pd.Series