openenergyid 0.1.7__py2.py3-none-any.whl → 0.1.8__py2.py3-none-any.whl

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.

Potentially problematic release.


This version of openenergyid might be problematic. Click here for more details.

openenergyid/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """Open Energy ID Python SDK."""
2
2
 
3
- __version__ = "0.1.7"
3
+ __version__ = "0.1.8"
4
4
 
5
5
  from .enums import Granularity
6
6
  from .models import TimeSeries
openenergyid/const.py ADDED
@@ -0,0 +1,13 @@
1
+ """Constants for the Open Energy ID package."""
2
+
3
+ from typing import Literal
4
+
5
+ # METRICS
6
+
7
+ ELECTRICITY_DELIVERED: Literal["electricity_delivered"] = "electricity_delivered"
8
+ ELECTRICITY_EXPORTED: Literal["electricity_exported"] = "electricity_exported"
9
+ ELECTRICITY_PRODUCED: Literal["electricity_produced"] = "electricity_produced"
10
+
11
+ PRICE_DAY_AHEAD: Literal["price_day_ahead"] = "price_day_ahead"
12
+ PRICE_IMBALANCE_UPWARD: Literal["price_imbalance_upward"] = "price_imbalance_upward"
13
+ PRICE_IMBALANCE_DOWNWARD: Literal["price_imbalance_downward"] = "price_imbalance_downward"
openenergyid/models.py CHANGED
@@ -1,6 +1,7 @@
1
1
  """Data models for the Open Energy ID."""
2
2
 
3
3
  import datetime as dt
4
+ from typing import Optional, overload
4
5
 
5
6
  import pandas as pd
6
7
  from pydantic import BaseModel
@@ -23,3 +24,44 @@ class TimeSeries(BaseModel):
23
24
  frame = pd.DataFrame(self.data, columns=self.columns, index=self.index)
24
25
  frame.index = pd.to_datetime(frame.index, utc=True)
25
26
  return frame.tz_convert(timezone)
27
+
28
+ @overload
29
+ def to_json(self, path: None = None, **kwargs) -> str:
30
+ ...
31
+
32
+ @overload
33
+ def to_json(self, path: str, **kwargs) -> None:
34
+ ...
35
+
36
+ def to_json(self, path: Optional[str] = None, **kwargs) -> Optional[str]:
37
+ """Save the TimeSeries to a JSON file or return as string."""
38
+ if path is None:
39
+ return self.model_dump_json(**kwargs)
40
+ else:
41
+ encoding = kwargs.pop("encoding", "UTF-8")
42
+ with open(path, "w", encoding=encoding) as file:
43
+ file.write(self.model_dump_json(**kwargs))
44
+
45
+ @overload
46
+ @classmethod
47
+ def from_json(cls, string: str, **kwargs) -> "TimeSeries":
48
+ ...
49
+
50
+ @overload
51
+ @classmethod
52
+ def from_json(cls, path: str, **kwargs) -> "TimeSeries":
53
+ ...
54
+
55
+ @classmethod
56
+ def from_json(
57
+ cls, string: Optional[str] = None, path: Optional[str] = None, **kwargs
58
+ ) -> "TimeSeries":
59
+ """Load the TimeSeries from a JSON file or string."""
60
+ if string:
61
+ return cls.model_validate_json(string, **kwargs)
62
+ elif path:
63
+ encoding = kwargs.pop("encoding", "UTF-8")
64
+ with open(path, "r", encoding=encoding) as file:
65
+ return cls.model_validate_json(file.read(), **kwargs)
66
+ else:
67
+ raise ValueError("Either string or path must be provided.")
openenergyid/mvlr/main.py CHANGED
@@ -17,6 +17,7 @@ def find_best_mvlr(
17
17
  y=data.dependent_variable,
18
18
  granularity=granularity,
19
19
  allow_negative_predictions=data.allow_negative_predictions,
20
+ single_use_exog_prefixes=data.single_use_exog_prefixes,
20
21
  )
21
22
  mvlr.do_analysis()
22
23
  if mvlr.validate(
@@ -67,6 +67,12 @@ class MultiVariableRegressionInput(BaseModel):
67
67
  validation_parameters: ValidationParameters = Field(
68
68
  alias="validationParameters", default=ValidationParameters()
69
69
  )
70
+ single_use_exog_prefixes: Optional[List[str]] = Field(
71
+ # default=["HDD", "CDD", "FDD"],
72
+ default=None,
73
+ alias="singleUseExogPrefixes",
74
+ description="List of prefixes to be used as single-use exogenous variables.",
75
+ )
70
76
 
71
77
  def model_post_init(self, __context: Any) -> None:
72
78
  """Post init hook."""
openenergyid/mvlr/mvlr.py CHANGED
@@ -40,6 +40,7 @@ class MultiVariableLinearRegression:
40
40
  cross_validation: bool = False,
41
41
  allow_negative_predictions: bool = False,
42
42
  granularity: Granularity = None,
43
+ single_use_exog_prefixes: list[str] = None,
43
44
  ):
44
45
  """Parameters
45
46
  ----------
@@ -62,6 +63,15 @@ class MultiVariableLinearRegression:
62
63
  If True, allow predictions to be negative.
63
64
  For gas consumption or PV production, this is not physical
64
65
  so allow_negative_predictions should be False
66
+ granularity : Granularity, default=None
67
+ Granularity of the data. Is only used for the output of the model.
68
+ If None, the granularity is not set.
69
+ single_use_exog_prefixes : list of str, default=None
70
+ List of variable prefixes that indicate a variable type that should only be used once.
71
+ For example, if the list contains "HDD", only one of the columns "HDD1", "HDD2", "HDD3" etc.
72
+ will be used as an independent variable.
73
+ Once the best fit using a variable with a given prefix is found, the other variables with the same
74
+ prefix will not be used as independent variables.
65
75
  """
66
76
  self.data = data.copy()
67
77
  if y not in self.data.columns:
@@ -76,6 +86,7 @@ class MultiVariableLinearRegression:
76
86
  self.cross_validation = cross_validation
77
87
  self.allow_negative_predictions = allow_negative_predictions
78
88
  self.granularity = granularity
89
+ self.single_use_exog_prefixes = single_use_exog_prefixes
79
90
  self._fit = None
80
91
  self._list_of_fits = []
81
92
  self.list_of_cverrors = []
@@ -166,6 +177,18 @@ class MultiVariableLinearRegression:
166
177
  else:
167
178
  self._list_of_fits.append(best_fit)
168
179
  all_model_terms_dict.pop(best_x)
180
+
181
+ # Check if `best_x` starts with a prefix that should only be used once
182
+ # If so, remove all other variables with the same prefix from the list of candidates
183
+ if self.single_use_exog_prefixes:
184
+ for prefix in self.single_use_exog_prefixes:
185
+ if best_x.startswith(prefix):
186
+ all_model_terms_dict = {
187
+ k: v
188
+ for k, v in all_model_terms_dict.items()
189
+ if not k.startswith(prefix)
190
+ }
191
+
169
192
  self._fit = self._list_of_fits[-1]
170
193
 
171
194
  def _do_analysis_cross_validation(self):
@@ -237,6 +260,17 @@ class MultiVariableLinearRegression:
237
260
  # next iteration with the found exog removed
238
261
  all_model_terms_dict.pop(best_x)
239
262
 
263
+ # Check if `best_x` starts with a prefix that should only be used once
264
+ # If so, remove all other variables with the same prefix from the list of candidates
265
+ if self.single_use_exog_prefixes:
266
+ for prefix in self.single_use_exog_prefixes:
267
+ if best_x.startswith(prefix):
268
+ all_model_terms_dict = {
269
+ k: v
270
+ for k, v in all_model_terms_dict.items()
271
+ if not k.startswith(prefix)
272
+ }
273
+
240
274
  self._fit = self._list_of_fits[-1]
241
275
 
242
276
  def _prune(self, fit: fm.ols, p_max: float) -> fm.ols:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openenergyid
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: Open Source Python library for energy analytics and simulations
5
5
  Project-URL: Homepage, https://energyid.eu
6
6
  Project-URL: Repository, https://github.com/EnergieID/OpenEnergyID
@@ -0,0 +1,13 @@
1
+ openenergyid/__init__.py,sha256=SddUHMaNL5tWsrK3W-8JyGXmxdYaeyxBhXqd1TsBChc,160
2
+ openenergyid/const.py,sha256=bF-U-r0Qj2GWCYBBxReg8fbv2D0V1JzfPMwSEQ5ZWds,569
3
+ openenergyid/enums.py,sha256=jdw4CB1gkisx0re_SesrTEyh_T-UxYp6uieE7iYlHdA,357
4
+ openenergyid/models.py,sha256=pUJpQCodph0NukiIpFdc9X6Zj6qEGQPSWoztYDwqyuE,2214
5
+ openenergyid/mvlr/__init__.py,sha256=Glrc218oqa8tq_Y2G9LXaSoN4Yba-vsjXUi9r9iPzaY,471
6
+ openenergyid/mvlr/helpers.py,sha256=fsx-gSvBdU31BjncFkRd1RySmSPPYgwflCnmSFzox2Q,961
7
+ openenergyid/mvlr/main.py,sha256=dwkl71u8HnlMAq-cmkwvI7z-XtlmqpvZRFoDc9CN-gg,1210
8
+ openenergyid/mvlr/models.py,sha256=ncQ0W0LLCP7IZ4rDgLwIPZRQpK4-xC-qA17BW9tMwio,7878
9
+ openenergyid/mvlr/mvlr.py,sha256=UbMuoWdepnGd1_heVtFOnLoBxVUB7WrPRLyOaDELxlI,18030
10
+ openenergyid-0.1.8.dist-info/METADATA,sha256=7S_S8PFQ8VtflEhBFwCCxVt46Nkqzyh_UL8T89PWXm4,2431
11
+ openenergyid-0.1.8.dist-info/WHEEL,sha256=ccEkY-EGGllEs7ySpwBlD8G4u70wR77CNej8Q6tzIqA,105
12
+ openenergyid-0.1.8.dist-info/licenses/LICENSE,sha256=NgRdcNHwyXVCXZ8sJwoTp0DCowThJ9LWWl4xhbV1IUY,1074
13
+ openenergyid-0.1.8.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.18.0
2
+ Generator: hatchling 1.21.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py2-none-any
5
5
  Tag: py3-none-any
@@ -1,12 +0,0 @@
1
- openenergyid/__init__.py,sha256=LWqiRKaHvmuTOpoTZcvQkgPhotMEc7tsuqzZ47Y1AKs,160
2
- openenergyid/enums.py,sha256=jdw4CB1gkisx0re_SesrTEyh_T-UxYp6uieE7iYlHdA,357
3
- openenergyid/models.py,sha256=w6YJHi1fysmLZYEI6peTfQAbMS92Kf5sk0VtXw7HrAM,813
4
- openenergyid/mvlr/__init__.py,sha256=Glrc218oqa8tq_Y2G9LXaSoN4Yba-vsjXUi9r9iPzaY,471
5
- openenergyid/mvlr/helpers.py,sha256=fsx-gSvBdU31BjncFkRd1RySmSPPYgwflCnmSFzox2Q,961
6
- openenergyid/mvlr/main.py,sha256=r4o3394jUd72sSJtIae67WDrGB7XP9ZMAiytpr3YFPw,1142
7
- openenergyid/mvlr/models.py,sha256=F8GrqtAK6bfR3Eur7hp3XjGj433bh4hZVRtGvg3DeUY,7625
8
- openenergyid/mvlr/mvlr.py,sha256=Cxgc-GeZpVuxvoRgP1Po7ttFdFArA5tW0fB8sihtikI,16063
9
- openenergyid-0.1.7.dist-info/METADATA,sha256=nDBrDk5TFlmzLFbMAiEnP_4A7QFceNL_RO5F6Mj1UmE,2431
10
- openenergyid-0.1.7.dist-info/WHEEL,sha256=fagL_Tj29mg80flwlxJNW45nBDbboxF04Tnbc_jt3Bg,105
11
- openenergyid-0.1.7.dist-info/licenses/LICENSE,sha256=NgRdcNHwyXVCXZ8sJwoTp0DCowThJ9LWWl4xhbV1IUY,1074
12
- openenergyid-0.1.7.dist-info/RECORD,,