Skip to content

Commit

Permalink
works for flat pflines, nested not yet
Browse files Browse the repository at this point in the history
  • Loading branch information
Alina Voilova committed Feb 20, 2024
1 parent 788a8d0 commit ebd4bce
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 21 deletions.
19 changes: 12 additions & 7 deletions dev_scripts/checks.py
Original file line number Diff line number Diff line change
@@ -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)
43 changes: 29 additions & 14 deletions portfolyo/core/shared/concat.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
# 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
# import itertools
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().
Expand All @@ -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
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down

0 comments on commit ebd4bce

Please sign in to comment.