From ebd4bced3be44a1f2818613d787a9133d67dc294 Mon Sep 17 00:00:00 2001 From: Alina Voilova Date: Tue, 20 Feb 2024 15:44:03 +0100 Subject: [PATCH] works for flat pflines, nested not yet --- dev_scripts/checks.py | 19 +++++++++------ portfolyo/core/shared/concat.py | 43 ++++++++++++++++++++++----------- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/dev_scripts/checks.py b/dev_scripts/checks.py index ac07d8b..07395f9 100644 --- a/dev_scripts/checks.py +++ b/dev_scripts/checks.py @@ -1,9 +1,14 @@ +import pandas as pd import portfolyo as pf -from portfolyo import tools +from portfolyo.core.shared import concat -pfl = pf.dev.get_nestedpfline() -pfl2 = pf.dev.get_nestedpfline() -pfls = [pfl, pfl2] -children_names_sets = [{name for name in pfl.children} for pfl in pfls] -start_of_day = tools.startofday.get(pfl.index, "str") -print(pfl) +index = pd.date_range("2020", "2024", freq="QS", inclusive="left") +index2 = pd.date_range("2024", "2025", freq="QS", inclusive="left") +pfl = pf.dev.get_nestedpfline(index) +pfl2 = pf.dev.get_nestedpfline(index2) + +concat.general(pfl, pfl2) + +# print(index) +# print(index2) +# print(pfl) diff --git a/portfolyo/core/shared/concat.py b/portfolyo/core/shared/concat.py index 1df90e8..0b0ee72 100644 --- a/portfolyo/core/shared/concat.py +++ b/portfolyo/core/shared/concat.py @@ -1,10 +1,17 @@ # import pandas as pd # import portfolyo as pf +from __future__ import annotations from typing import TYPE_CHECKING, Union, List + +import pandas as pd + +from portfolyo.core.pfline import create from ..pfline import classes from collections import defaultdict from ..pfline.enums import Structure +# from ..pfline.dataframeexport import Flat, Nested + if TYPE_CHECKING: # needed to avoid circular imports from ..pfline import PfLine from ..pfstate import PfState @@ -12,7 +19,7 @@ from portfolyo import tools -def general(pfl_or_pfs: Union[PfLine, PfState]) -> None: +def general(*pfl_or_pfs: Union[PfLine, PfState]) -> None: """ Based on passed parameters calls either concat_pflines() or concat_pfstates(). @@ -26,19 +33,18 @@ def general(pfl_or_pfs: Union[PfLine, PfState]) -> None: None """ - if isinstance(pfl_or_pfs, classes.FlatPfLine) or isinstance( - pfl_or_pfs, classes.NestedPfLine - ): - concat_pflines(pfl_or_pfs) - elif isinstance(pfl_or_pfs, PfState): - concat_pfstates(pfl_or_pfs) + + if all(isinstance(item, classes.PfLine) for item in pfl_or_pfs): + concat_pflines(*pfl_or_pfs) + elif all(isinstance(item, classes.PfState) for item in pfl_or_pfs): + concat_pfstates(*pfl_or_pfs) else: raise NotImplementedError( "Concatenation is implemented only for PfState or PfLine." ) -def concat_pflines(pfls: List[PfLine]) -> PfLine: +def concat_pflines(*pfls: PfLine) -> PfLine: """ This only works if the input portfolio lines have contain compatible information: (the same frequency, timezone, start-of-day, kind, etc) and @@ -80,7 +86,7 @@ def concat_pflines(pfls: List[PfLine]) -> PfLine: "Not possible to concatenate PfLines of different start_of_day." ) # we can concatenate only pflines of the same type: nested of flat - # with this test and check wether pfls are the same types and they have the same number of children + # with this test and check whether pfls are the same types and they have the same number of children if len({pfl.structure for pfl in pfls}) != 1: raise TypeError("Not possible to concatenate PfLines of different structures.") if pfls[0].structure is Structure.NESTED: @@ -91,17 +97,26 @@ def concat_pflines(pfls: List[PfLine]) -> PfLine: for name, children in sorted_children.items(): if len(children) != len(pfls): raise ValueError - # If we reach here, all pfls have same kind, same number and names of children. children_names_sets = [{name for name in pfl.children} for pfl in pfls] if len(children_names_sets) != len(pfls[0].children): raise TypeError( "Not possible to concatenate PfLines with different children names." ) - - # TODO: concat(a,b and concat(b,a) should give the same result) - # TODO: we can probably to create pfline to check gapplesnes and overplap, - # it's supposed to give error + # If we reach here, all pfls have same kind, same number and names of children. + + # concat(a,b) and concat(b,a) should give the same result: + sorted_pfls = sorted(pfls, key=lambda pfl: pfl.index[0]) + # call the constructor of pfl to check check gapplesnes and overplap + dataframes = [ + pfl.dataframe() for pfl in sorted_pfls + ] # will it work regardless of structure? + # concatenate dataframes into one + concat_data = pd.concat(dataframes, axis=0) + print("Data", concat_data) + # create pfline from dataframes + concat_pfls = create.pfline(concat_data) + print("Concatenate pfls", concat_pfls) def concat_pfstates(pfs: List[PfState]) -> PfState: