eb-evaluation 0.2.3__tar.gz → 0.2.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {eb_evaluation-0.2.3/src/eb_evaluation.egg-info → eb_evaluation-0.2.7}/PKG-INFO +23 -13
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/README.md +12 -12
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/pyproject.toml +21 -3
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/src/eb_evaluation/__init__.py +14 -27
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/src/eb_evaluation/adjustment/__init__.py +3 -1
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/src/eb_evaluation/adjustment/_utils.py +8 -10
- eb_evaluation-0.2.7/src/eb_evaluation/adjustment/ral.py +534 -0
- eb_evaluation-0.2.7/src/eb_evaluation/dataframe/__init__.py +55 -0
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/src/eb_evaluation/dataframe/entity.py +51 -42
- eb_evaluation-0.2.7/src/eb_evaluation/dataframe/governance_panel.py +234 -0
- eb_evaluation-0.2.7/src/eb_evaluation/dataframe/governance_workflow.py +202 -0
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/src/eb_evaluation/dataframe/group.py +61 -70
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/src/eb_evaluation/dataframe/hierarchy.py +32 -38
- eb_evaluation-0.2.7/src/eb_evaluation/dataframe/levels.py +141 -0
- eb_evaluation-0.2.7/src/eb_evaluation/dataframe/panel.py +255 -0
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/src/eb_evaluation/dataframe/single.py +12 -21
- eb_evaluation-0.2.7/src/eb_evaluation/diagnostics/__init__.py +203 -0
- eb_evaluation-0.2.7/src/eb_evaluation/diagnostics/dqc.py +440 -0
- eb_evaluation-0.2.7/src/eb_evaluation/diagnostics/fas.py +410 -0
- eb_evaluation-0.2.7/src/eb_evaluation/diagnostics/fpc.py +323 -0
- eb_evaluation-0.2.7/src/eb_evaluation/diagnostics/governance.py +353 -0
- eb_evaluation-0.2.7/src/eb_evaluation/diagnostics/presets.py +250 -0
- eb_evaluation-0.2.7/src/eb_evaluation/diagnostics/results.py +340 -0
- eb_evaluation-0.2.7/src/eb_evaluation/diagnostics/run.py +327 -0
- eb_evaluation-0.2.7/src/eb_evaluation/diagnostics/validate.py +384 -0
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/src/eb_evaluation/model_selection/auto_engine.py +126 -71
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/src/eb_evaluation/model_selection/compare.py +69 -46
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/src/eb_evaluation/model_selection/cwsl_regressor.py +29 -43
- eb_evaluation-0.2.7/src/eb_evaluation/model_selection/electric_barometer.py +918 -0
- eb_evaluation-0.2.7/src/eb_evaluation/utils/validation.py +95 -0
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7/src/eb_evaluation.egg-info}/PKG-INFO +23 -13
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/src/eb_evaluation.egg-info/SOURCES.txt +13 -4
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/src/eb_evaluation.egg-info/requires.txt +13 -1
- eb_evaluation-0.2.3/src/eb_evaluation/adjustment/readiness_adjustment.py +0 -652
- eb_evaluation-0.2.3/src/eb_evaluation/dataframe/__init__.py +0 -40
- eb_evaluation-0.2.3/src/eb_evaluation/dataframe/cost_ratio.py +0 -224
- eb_evaluation-0.2.3/src/eb_evaluation/dataframe/panel.py +0 -141
- eb_evaluation-0.2.3/src/eb_evaluation/dataframe/sensitivity.py +0 -192
- eb_evaluation-0.2.3/src/eb_evaluation/dataframe/tolerance.py +0 -674
- eb_evaluation-0.2.3/src/eb_evaluation/model_selection/electric_barometer.py +0 -499
- eb_evaluation-0.2.3/src/eb_evaluation/utils/validation.py +0 -100
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/LICENSE +0 -0
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/setup.cfg +0 -0
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/src/eb_evaluation/model_selection/__init__.py +3 -3
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/src/eb_evaluation/utils/__init__.py +0 -0
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/src/eb_evaluation.egg-info/dependency_links.txt +0 -0
- {eb_evaluation-0.2.3 → eb_evaluation-0.2.7}/src/eb_evaluation.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: eb-evaluation
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.7
|
|
4
4
|
Summary: Electric Barometer: DataFrame-based evaluation utilities for CWSL and related metrics.
|
|
5
5
|
Author-email: "Kyle Corrie (Economistician)" <kcorrie@economistician.com>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -21,14 +21,24 @@ Description-Content-Type: text/markdown
|
|
|
21
21
|
License-File: LICENSE
|
|
22
22
|
Requires-Dist: numpy>=1.24
|
|
23
23
|
Requires-Dist: pandas>=2.0
|
|
24
|
+
Requires-Dist: scikit-learn>=1.3
|
|
24
25
|
Requires-Dist: eb-metrics<0.3,>=0.2
|
|
25
26
|
Requires-Dist: eb-adapters<0.3,>=0.2
|
|
26
27
|
Provides-Extra: test
|
|
27
28
|
Requires-Dist: pytest>=8.0; extra == "test"
|
|
28
|
-
Requires-Dist: scikit-learn>=1.3; extra == "test"
|
|
29
29
|
Provides-Extra: dev
|
|
30
30
|
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
31
31
|
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
32
|
+
Provides-Extra: boosting
|
|
33
|
+
Requires-Dist: xgboost>=2.0; extra == "boosting"
|
|
34
|
+
Requires-Dist: lightgbm>=4.0; extra == "boosting"
|
|
35
|
+
Requires-Dist: catboost>=1.2; extra == "boosting"
|
|
36
|
+
Provides-Extra: all
|
|
37
|
+
Requires-Dist: pytest>=8.0; extra == "all"
|
|
38
|
+
Requires-Dist: pytest-cov>=5.0; extra == "all"
|
|
39
|
+
Requires-Dist: xgboost>=2.0; extra == "all"
|
|
40
|
+
Requires-Dist: lightgbm>=4.0; extra == "all"
|
|
41
|
+
Requires-Dist: catboost>=1.2; extra == "all"
|
|
32
42
|
Dynamic: license-file
|
|
33
43
|
|
|
34
44
|
# Electric Barometer · Evaluation (`eb-evaluation`)
|
|
@@ -46,7 +56,7 @@ Evaluation and model selection utilities for applying Electric Barometer metrics
|
|
|
46
56
|
|
|
47
57
|
`eb-evaluation` provides the evaluation and model selection layer of the Electric Barometer ecosystem. It applies metric primitives to forecasts and observations across entities, groups, and hierarchical structures, enabling consistent assessment of forecasting performance in operational settings.
|
|
48
58
|
|
|
49
|
-
The package focuses on DataFrame-first evaluation workflows, including
|
|
59
|
+
The package focuses on DataFrame-first evaluation workflows, including cost-sensitive comparison, tolerance-aware scoring given explicit thresholds, and readiness-oriented adjustment logic. It does not define feature construction or model interfaces; instead, it consumes standardized inputs from upstream layers and produces evaluation outputs that can be used for model selection, reporting, and decision support.
|
|
50
60
|
|
|
51
61
|
---
|
|
52
62
|
|
|
@@ -75,35 +85,35 @@ The package supports Python 3.10 and later.
|
|
|
75
85
|
## Core Concepts
|
|
76
86
|
|
|
77
87
|
- **DataFrame-first evaluation** — Evaluation logic operates directly on tabular forecast and observation data, enabling transparent aggregation, grouping, and comparison across entities and hierarchies.
|
|
78
|
-
- **Cost- and tolerance-aware scoring** — Forecast performance is assessed using metrics that reflect asymmetric cost
|
|
88
|
+
- **Cost- and tolerance-aware scoring** — Forecast performance is assessed using metrics that reflect asymmetric cost and explicitly supplied deviation thresholds, rather than purely symmetric statistical error.
|
|
79
89
|
- **Hierarchical and panel semantics** — Evaluation respects entity boundaries, grouping structure, and temporal alignment, ensuring correctness in multi-level forecasting environments.
|
|
80
90
|
- **Model comparability** — Forecasts produced by heterogeneous models can be evaluated and compared using a consistent set of metrics and aggregation rules.
|
|
81
|
-
- **Readiness-oriented selection** — Model selection emphasizes execution feasibility and operational adequacy, not just aggregate accuracy, supporting decision-aligned forecasting workflows.
|
|
91
|
+
- **Readiness-oriented selection** — Model selection emphasizes execution feasibility and operational adequacy as reflected in evaluation metrics, not just aggregate accuracy, supporting decision-aligned forecasting workflows.
|
|
82
92
|
|
|
83
93
|
---
|
|
84
94
|
|
|
85
95
|
## Minimal Example
|
|
86
96
|
|
|
87
|
-
The example below shows how
|
|
97
|
+
The example below shows how forecast accuracy can be evaluated across entities
|
|
98
|
+
using Electric Barometer metrics in a DataFrame-first workflow.
|
|
88
99
|
|
|
89
100
|
```python
|
|
90
101
|
import pandas as pd
|
|
91
|
-
from eb_evaluation.dataframe
|
|
102
|
+
from eb_evaluation.dataframe import compute_cwsl_df
|
|
92
103
|
|
|
93
104
|
# Example evaluation data
|
|
94
105
|
df = pd.DataFrame({
|
|
95
106
|
"entity_id": ["A", "A", "B", "B"],
|
|
96
107
|
"date": pd.to_datetime(["2024-01-01", "2024-01-02"] * 2),
|
|
97
108
|
"actual": [10, 12, 7, 9],
|
|
98
|
-
"
|
|
99
|
-
"model_b": [11, 13, 6, 8],
|
|
109
|
+
"prediction": [9, 11, 8, 10],
|
|
100
110
|
})
|
|
101
111
|
|
|
102
|
-
#
|
|
103
|
-
results =
|
|
112
|
+
# Compute Cost-Weighted Service Loss (CWSL)
|
|
113
|
+
results = compute_cwsl_df(
|
|
104
114
|
df,
|
|
105
115
|
actual_col="actual",
|
|
106
|
-
|
|
116
|
+
prediction_col="prediction",
|
|
107
117
|
entity_col="entity_id",
|
|
108
118
|
time_col="date",
|
|
109
119
|
)
|
|
@@ -115,5 +125,5 @@ print(results)
|
|
|
115
125
|
|
|
116
126
|
## License
|
|
117
127
|
|
|
118
|
-
BSD 3-Clause License.
|
|
128
|
+
BSD 3-Clause License.
|
|
119
129
|
© 2025 Kyle Corrie.
|
|
@@ -13,7 +13,7 @@ Evaluation and model selection utilities for applying Electric Barometer metrics
|
|
|
13
13
|
|
|
14
14
|
`eb-evaluation` provides the evaluation and model selection layer of the Electric Barometer ecosystem. It applies metric primitives to forecasts and observations across entities, groups, and hierarchical structures, enabling consistent assessment of forecasting performance in operational settings.
|
|
15
15
|
|
|
16
|
-
The package focuses on DataFrame-first evaluation workflows, including
|
|
16
|
+
The package focuses on DataFrame-first evaluation workflows, including cost-sensitive comparison, tolerance-aware scoring given explicit thresholds, and readiness-oriented adjustment logic. It does not define feature construction or model interfaces; instead, it consumes standardized inputs from upstream layers and produces evaluation outputs that can be used for model selection, reporting, and decision support.
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
@@ -42,35 +42,35 @@ The package supports Python 3.10 and later.
|
|
|
42
42
|
## Core Concepts
|
|
43
43
|
|
|
44
44
|
- **DataFrame-first evaluation** — Evaluation logic operates directly on tabular forecast and observation data, enabling transparent aggregation, grouping, and comparison across entities and hierarchies.
|
|
45
|
-
- **Cost- and tolerance-aware scoring** — Forecast performance is assessed using metrics that reflect asymmetric cost
|
|
45
|
+
- **Cost- and tolerance-aware scoring** — Forecast performance is assessed using metrics that reflect asymmetric cost and explicitly supplied deviation thresholds, rather than purely symmetric statistical error.
|
|
46
46
|
- **Hierarchical and panel semantics** — Evaluation respects entity boundaries, grouping structure, and temporal alignment, ensuring correctness in multi-level forecasting environments.
|
|
47
47
|
- **Model comparability** — Forecasts produced by heterogeneous models can be evaluated and compared using a consistent set of metrics and aggregation rules.
|
|
48
|
-
- **Readiness-oriented selection** — Model selection emphasizes execution feasibility and operational adequacy, not just aggregate accuracy, supporting decision-aligned forecasting workflows.
|
|
48
|
+
- **Readiness-oriented selection** — Model selection emphasizes execution feasibility and operational adequacy as reflected in evaluation metrics, not just aggregate accuracy, supporting decision-aligned forecasting workflows.
|
|
49
49
|
|
|
50
50
|
---
|
|
51
51
|
|
|
52
52
|
## Minimal Example
|
|
53
53
|
|
|
54
|
-
The example below shows how
|
|
54
|
+
The example below shows how forecast accuracy can be evaluated across entities
|
|
55
|
+
using Electric Barometer metrics in a DataFrame-first workflow.
|
|
55
56
|
|
|
56
57
|
```python
|
|
57
58
|
import pandas as pd
|
|
58
|
-
from eb_evaluation.dataframe
|
|
59
|
+
from eb_evaluation.dataframe import compute_cwsl_df
|
|
59
60
|
|
|
60
61
|
# Example evaluation data
|
|
61
62
|
df = pd.DataFrame({
|
|
62
63
|
"entity_id": ["A", "A", "B", "B"],
|
|
63
64
|
"date": pd.to_datetime(["2024-01-01", "2024-01-02"] * 2),
|
|
64
65
|
"actual": [10, 12, 7, 9],
|
|
65
|
-
"
|
|
66
|
-
"model_b": [11, 13, 6, 8],
|
|
66
|
+
"prediction": [9, 11, 8, 10],
|
|
67
67
|
})
|
|
68
68
|
|
|
69
|
-
#
|
|
70
|
-
results =
|
|
69
|
+
# Compute Cost-Weighted Service Loss (CWSL)
|
|
70
|
+
results = compute_cwsl_df(
|
|
71
71
|
df,
|
|
72
72
|
actual_col="actual",
|
|
73
|
-
|
|
73
|
+
prediction_col="prediction",
|
|
74
74
|
entity_col="entity_id",
|
|
75
75
|
time_col="date",
|
|
76
76
|
)
|
|
@@ -82,5 +82,5 @@ print(results)
|
|
|
82
82
|
|
|
83
83
|
## License
|
|
84
84
|
|
|
85
|
-
BSD 3-Clause License.
|
|
86
|
-
© 2025 Kyle Corrie.
|
|
85
|
+
BSD 3-Clause License.
|
|
86
|
+
© 2025 Kyle Corrie.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
######################################
|
|
4
4
|
[project]
|
|
5
5
|
name = "eb-evaluation"
|
|
6
|
-
version = "0.2.
|
|
6
|
+
version = "0.2.7"
|
|
7
7
|
description = "Electric Barometer: DataFrame-based evaluation utilities for CWSL and related metrics."
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
requires-python = ">=3.10"
|
|
@@ -39,6 +39,7 @@ classifiers = [
|
|
|
39
39
|
dependencies = [
|
|
40
40
|
"numpy>=1.24",
|
|
41
41
|
"pandas>=2.0",
|
|
42
|
+
"scikit-learn>=1.3",
|
|
42
43
|
|
|
43
44
|
# Electric Barometer compatibility band (0.2.x)
|
|
44
45
|
"eb-metrics>=0.2,<0.3",
|
|
@@ -62,7 +63,6 @@ Documentation = "https://github.com/Economistician/eb-docs"
|
|
|
62
63
|
# CI / test-only dependencies
|
|
63
64
|
test = [
|
|
64
65
|
"pytest>=8.0",
|
|
65
|
-
"scikit-learn>=1.3",
|
|
66
66
|
]
|
|
67
67
|
|
|
68
68
|
# Local developer tooling
|
|
@@ -71,6 +71,24 @@ dev = [
|
|
|
71
71
|
"pytest-cov>=5.0",
|
|
72
72
|
]
|
|
73
73
|
|
|
74
|
+
# Optional "boosting engines" commonly used in the AutoEngine zoo.
|
|
75
|
+
# These are intentionally extras because they can be heavy / platform-specific.
|
|
76
|
+
boosting = [
|
|
77
|
+
"xgboost>=2.0",
|
|
78
|
+
"lightgbm>=4.0",
|
|
79
|
+
"catboost>=1.2",
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
# Combined extra to satisfy the "extras: all" CI contract.
|
|
83
|
+
# Aggregates optional test + dev tooling + optional engines.
|
|
84
|
+
all = [
|
|
85
|
+
"pytest>=8.0",
|
|
86
|
+
"pytest-cov>=5.0",
|
|
87
|
+
"xgboost>=2.0",
|
|
88
|
+
"lightgbm>=4.0",
|
|
89
|
+
"catboost>=1.2",
|
|
90
|
+
]
|
|
91
|
+
|
|
74
92
|
######################################
|
|
75
93
|
# Build system
|
|
76
94
|
######################################
|
|
@@ -89,4 +107,4 @@ where = ["src"]
|
|
|
89
107
|
######################################
|
|
90
108
|
[tool.pytest.ini_options]
|
|
91
109
|
pythonpath = ["src"]
|
|
92
|
-
addopts = "-ra"
|
|
110
|
+
addopts = "-ra"
|
|
@@ -12,7 +12,7 @@ architecture:
|
|
|
12
12
|
|
|
13
13
|
- ``eb_metrics`` defines **metric math** (CWSL, NSL, UD, HR@τ, FRS, etc.)
|
|
14
14
|
- ``eb-evaluation`` provides **tabular orchestration**, grouping logic,
|
|
15
|
-
|
|
15
|
+
and model selection
|
|
16
16
|
|
|
17
17
|
Primary capabilities include:
|
|
18
18
|
|
|
@@ -20,13 +20,8 @@ DataFrame evaluation
|
|
|
20
20
|
- Single-slice and grouped CWSL computation
|
|
21
21
|
- Hierarchical evaluation across multiple aggregation levels
|
|
22
22
|
- Long-form (tidy) panel outputs for plotting and reporting
|
|
23
|
-
- Entity-aware evaluation
|
|
24
|
-
-
|
|
25
|
-
|
|
26
|
-
Tolerance (τ) calibration
|
|
27
|
-
- Data-driven τ estimation from historical residuals
|
|
28
|
-
- Global and entity-level τ estimation with governance guards
|
|
29
|
-
- HR@τ computation with automatically selected tolerances
|
|
23
|
+
- Entity-aware evaluation using externally supplied entity-specific cost ratios
|
|
24
|
+
- Governance-oriented evaluation and workflow orchestration
|
|
30
25
|
|
|
31
26
|
Model selection
|
|
32
27
|
- Cost-aware comparison of forecast models
|
|
@@ -42,41 +37,33 @@ Design principles
|
|
|
42
37
|
- **Deterministic & explicit**: no hidden heuristics; all behavior is
|
|
43
38
|
controlled via parameters and documented outputs.
|
|
44
39
|
|
|
40
|
+
Optimization utilities such as tolerance (τ) calibration, cost-ratio estimation,
|
|
41
|
+
and sensitivity sweeps live exclusively in ``eb-optimization``.
|
|
42
|
+
|
|
45
43
|
This package is intended to be used alongside ``eb_metrics`` and
|
|
46
44
|
``eb-adapters`` as part of the broader Electric Barometer ecosystem.
|
|
47
45
|
"""
|
|
48
46
|
|
|
47
|
+
from __future__ import annotations
|
|
48
|
+
|
|
49
49
|
from .dataframe import (
|
|
50
50
|
compute_cwsl_df,
|
|
51
|
+
evaluate_governance_panel_df,
|
|
51
52
|
evaluate_groups_df,
|
|
52
53
|
evaluate_hierarchy_df,
|
|
53
54
|
evaluate_panel_df,
|
|
54
55
|
evaluate_panel_with_entity_R,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
estimate_entity_R_from_balance,
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
from .dataframe.tolerance import (
|
|
61
|
-
hr_at_tau,
|
|
62
|
-
estimate_tau,
|
|
63
|
-
estimate_entity_tau,
|
|
64
|
-
hr_auto_tau,
|
|
65
|
-
TauEstimate,
|
|
56
|
+
run_governance_workflow_df,
|
|
57
|
+
run_governance_workflow_df_dict,
|
|
66
58
|
)
|
|
67
59
|
|
|
68
60
|
__all__ = [
|
|
69
61
|
"compute_cwsl_df",
|
|
62
|
+
"evaluate_governance_panel_df",
|
|
70
63
|
"evaluate_groups_df",
|
|
71
64
|
"evaluate_hierarchy_df",
|
|
72
65
|
"evaluate_panel_df",
|
|
73
66
|
"evaluate_panel_with_entity_R",
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"estimate_entity_R_from_balance",
|
|
77
|
-
"hr_at_tau",
|
|
78
|
-
"estimate_tau",
|
|
79
|
-
"estimate_entity_tau",
|
|
80
|
-
"hr_auto_tau",
|
|
81
|
-
"TauEstimate",
|
|
67
|
+
"run_governance_workflow_df",
|
|
68
|
+
"run_governance_workflow_df_dict",
|
|
82
69
|
]
|
|
@@ -16,10 +16,12 @@ Key ideas
|
|
|
16
16
|
Public API
|
|
17
17
|
----------
|
|
18
18
|
- `ReadinessAdjustmentLayer`
|
|
19
|
+
- `apply_ral`
|
|
19
20
|
"""
|
|
20
21
|
|
|
21
|
-
from .
|
|
22
|
+
from .ral import ReadinessAdjustmentLayer, apply_ral
|
|
22
23
|
|
|
23
24
|
__all__ = [
|
|
24
25
|
"ReadinessAdjustmentLayer",
|
|
26
|
+
"apply_ral",
|
|
25
27
|
]
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
1
|
"""
|
|
4
2
|
Internal utilities for the Readiness Adjustment Layer.
|
|
5
3
|
|
|
@@ -8,17 +6,17 @@ implementation. These utilities are **not** part of the public API and may chang
|
|
|
8
6
|
notice.
|
|
9
7
|
|
|
10
8
|
The intent is to keep the main algorithm (and its public surface area) in
|
|
11
|
-
`eb_evaluation.adjustment.
|
|
9
|
+
`eb_evaluation.adjustment.ral` clean and readable.
|
|
12
10
|
"""
|
|
13
11
|
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
14
|
from collections.abc import Callable, Sequence
|
|
15
|
-
from typing import Any, Union, overload
|
|
16
15
|
|
|
17
16
|
import numpy as np
|
|
18
17
|
import pandas as pd
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
ArrayLike = Union[np.ndarray, Sequence[float], pd.Series, pd.DataFrame]
|
|
19
|
+
ArrayLike = np.ndarray | Sequence[float] | pd.Series | pd.DataFrame
|
|
22
20
|
|
|
23
21
|
|
|
24
22
|
# ---------------------------------------------------------------------------
|
|
@@ -57,7 +55,7 @@ def validate_numeric_array(arr: ArrayLike, name: str = "array") -> np.ndarray:
|
|
|
57
55
|
- This helper does *not* drop missing values. If you need filtering behavior, perform
|
|
58
56
|
it upstream and call this only once the array should be clean.
|
|
59
57
|
"""
|
|
60
|
-
if isinstance(arr,
|
|
58
|
+
if isinstance(arr, pd.Series | pd.DataFrame):
|
|
61
59
|
arr = arr.to_numpy()
|
|
62
60
|
|
|
63
61
|
out = np.asarray(arr, dtype=float)
|
|
@@ -105,15 +103,15 @@ def safe_mean(values: np.ndarray) -> float:
|
|
|
105
103
|
# ---------------------------------------------------------------------------
|
|
106
104
|
def groupby_apply_values(
|
|
107
105
|
df: pd.DataFrame,
|
|
108
|
-
group_cols:
|
|
106
|
+
group_cols: str | Sequence[str],
|
|
109
107
|
value_col: str,
|
|
110
108
|
func: Callable[[np.ndarray], float],
|
|
111
109
|
) -> pd.DataFrame:
|
|
112
110
|
"""Apply a numeric reducer to a column, grouped by one or more keys.
|
|
113
111
|
|
|
114
112
|
This helper groups ``df`` by ``group_cols`` and applies ``func`` to the values of
|
|
115
|
-
``value_col`` for each group. The function is called with a
|
|
116
|
-
|
|
113
|
+
``value_col`` for each group. The function is called with a validated, finite float
|
|
114
|
+
array.
|
|
117
115
|
|
|
118
116
|
Parameters
|
|
119
117
|
----------
|