|
| 1 | + |
1 | 2 | from ..utils.misc import _isinstance_no_import |
2 | 3 |
|
3 | 4 | # Source prefixes in use at each SASE. |
@@ -75,3 +76,35 @@ def _select_subcomponent_trains(src, keys, dst=None): |
75 | 76 | setattr(dst, key, prop.select_trains(trains)) |
76 | 77 |
|
77 | 78 | return dst |
| 79 | + |
| 80 | + |
| 81 | +from collections.abc import Sequence |
| 82 | +from typing import Protocol, Self, runtime_checkable |
| 83 | +import pandas as pd |
| 84 | +from extra_data import by_id |
| 85 | + |
| 86 | + |
| 87 | +@runtime_checkable |
| 88 | +class TrainData(Protocol): |
| 89 | + train_ids: Sequence[int] |
| 90 | + |
| 91 | + def select_trains(self, train_sel) -> Self: |
| 92 | + raise NotImplementedError('select_trains') |
| 93 | + |
| 94 | + def data_counts(self, labelled=True) -> pd.Series: |
| 95 | + raise NotImplementedError('data_counts') |
| 96 | + |
| 97 | + |
| 98 | +def align(*unaligned): |
| 99 | + counts = pd.concat([ |
| 100 | + obj.data_counts() for obj in unaligned |
| 101 | + if isinstance(obj, TrainData) |
| 102 | + ], axis=1, join='inner') |
| 103 | + |
| 104 | + if len(counts.columns) != len(unaligned): |
| 105 | + raise TypeError('one or more passed objects do not implement ' |
| 106 | + 'the TrainData protocol') |
| 107 | + |
| 108 | + train_ids = counts.index[(counts > 0).all(axis=1)].to_numpy() |
| 109 | + |
| 110 | + return [obj.select_trains(by_id[train_ids]) for obj in unaligned] |
0 commit comments