volue-insight-timeseries 1.2.2__tar.gz → 1.2.3__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.

Potentially problematic release.


This version of volue-insight-timeseries might be problematic. Click here for more details.

Files changed (19) hide show
  1. {volue_insight_timeseries-1.2.2 → volue_insight_timeseries-1.2.3}/PKG-INFO +1 -1
  2. volue_insight_timeseries-1.2.3/volue_insight_timeseries/VERSION +1 -0
  3. {volue_insight_timeseries-1.2.2 → volue_insight_timeseries-1.2.3}/volue_insight_timeseries/util.py +77 -59
  4. {volue_insight_timeseries-1.2.2 → volue_insight_timeseries-1.2.3}/volue_insight_timeseries.egg-info/PKG-INFO +1 -1
  5. volue_insight_timeseries-1.2.2/volue_insight_timeseries/VERSION +0 -1
  6. {volue_insight_timeseries-1.2.2 → volue_insight_timeseries-1.2.3}/LICENSE +0 -0
  7. {volue_insight_timeseries-1.2.2 → volue_insight_timeseries-1.2.3}/MANIFEST.in +0 -0
  8. {volue_insight_timeseries-1.2.2 → volue_insight_timeseries-1.2.3}/README.md +0 -0
  9. {volue_insight_timeseries-1.2.2 → volue_insight_timeseries-1.2.3}/setup.cfg +0 -0
  10. {volue_insight_timeseries-1.2.2 → volue_insight_timeseries-1.2.3}/setup.py +0 -0
  11. {volue_insight_timeseries-1.2.2 → volue_insight_timeseries-1.2.3}/volue_insight_timeseries/__init__.py +0 -0
  12. {volue_insight_timeseries-1.2.2 → volue_insight_timeseries-1.2.3}/volue_insight_timeseries/auth.py +0 -0
  13. {volue_insight_timeseries-1.2.2 → volue_insight_timeseries-1.2.3}/volue_insight_timeseries/curves.py +0 -0
  14. {volue_insight_timeseries-1.2.2 → volue_insight_timeseries-1.2.3}/volue_insight_timeseries/events.py +0 -0
  15. {volue_insight_timeseries-1.2.2 → volue_insight_timeseries-1.2.3}/volue_insight_timeseries/session.py +0 -0
  16. {volue_insight_timeseries-1.2.2 → volue_insight_timeseries-1.2.3}/volue_insight_timeseries.egg-info/SOURCES.txt +0 -0
  17. {volue_insight_timeseries-1.2.2 → volue_insight_timeseries-1.2.3}/volue_insight_timeseries.egg-info/dependency_links.txt +0 -0
  18. {volue_insight_timeseries-1.2.2 → volue_insight_timeseries-1.2.3}/volue_insight_timeseries.egg-info/requires.txt +0 -0
  19. {volue_insight_timeseries-1.2.2 → volue_insight_timeseries-1.2.3}/volue_insight_timeseries.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: volue_insight_timeseries
3
- Version: 1.2.2
3
+ Version: 1.2.3
4
4
  Summary: Volue Insight API python library
5
5
  Home-page: https://www.volueinsight.com
6
6
  Author: Volue Insight
@@ -10,6 +10,7 @@ import pandas as pd
10
10
  import numpy as np
11
11
  import warnings
12
12
  from past.types import basestring
13
+
13
14
  try:
14
15
  from urllib.parse import quote_plus
15
16
  except ImportError:
@@ -19,44 +20,45 @@ from zoneinfo._common import ZoneInfoNotFoundError
19
20
 
20
21
 
21
22
  # Curve types
22
- TIME_SERIES = 'TIME_SERIES'
23
- TAGGED = 'TAGGED'
24
- INSTANCES = 'INSTANCES'
25
- TAGGED_INSTANCES = 'TAGGED_INSTANCES'
23
+ TIME_SERIES = "TIME_SERIES"
24
+ TAGGED = "TAGGED"
25
+ INSTANCES = "INSTANCES"
26
+ TAGGED_INSTANCES = "TAGGED_INSTANCES"
26
27
 
27
28
 
28
29
  # Frequency mapping from TS to Pandas
29
30
  _TS_FREQ_TABLE = {
30
- 'Y': 'YS',
31
- 'S': '2QS',
32
- 'Q': 'QS',
33
- 'M': 'MS',
34
- 'W': 'W-MON',
35
- 'H12': '12h',
36
- 'H6': '6h',
37
- 'H3': '3h',
38
- 'MIN30': '30min',
39
- 'MIN15': '15min',
40
- 'MIN5': '5min',
41
- 'MIN': 'min',
42
- 'D': 'D',
31
+ "Y": "YS",
32
+ "S": "2QS",
33
+ "Q": "QS",
34
+ "M": "MS",
35
+ "W": "W-MON",
36
+ "H12": "12h",
37
+ "H6": "6h",
38
+ "H3": "3h",
39
+ "H": "h",
40
+ "MIN30": "30min",
41
+ "MIN15": "15min",
42
+ "MIN5": "5min",
43
+ "MIN": "min",
44
+ "D": "D",
43
45
  }
44
46
 
45
47
  # Mapping from various versions of Pandas to TS is built from map above,
46
48
  # with some additions to support older versions of pandas
47
49
  _PANDAS_FREQ_TABLE = {
48
- 'YS-JAN': 'Y',
49
- 'AS-JAN': 'Y',
50
- 'AS': 'Y',
51
- '2QS-JAN': 'S',
52
- 'QS-JAN': 'Q',
53
- '12H': 'H12',
54
- '6H': 'H6',
55
- '3H': 'H3',
56
- '30T': 'MIN30',
57
- '15T': 'MIN15',
58
- '5T': 'MIN5',
59
- 'T': 'MIN',
50
+ "YS-JAN": "Y",
51
+ "AS-JAN": "Y",
52
+ "AS": "Y",
53
+ "2QS-JAN": "S",
54
+ "QS-JAN": "Q",
55
+ "12H": "H12",
56
+ "6H": "H6",
57
+ "3H": "H3",
58
+ "30T": "MIN30",
59
+ "15T": "MIN15",
60
+ "5T": "MIN5",
61
+ "T": "MIN",
60
62
  }
61
63
  for ts_freq, pandas_freq in _TS_FREQ_TABLE.items():
62
64
  _PANDAS_FREQ_TABLE[pandas_freq.upper()] = ts_freq
@@ -70,8 +72,10 @@ class TS(object):
70
72
  """
71
73
  A class to hold a basic time series.
72
74
  """
73
- def __init__(self, id=None, name=None, frequency=None, time_zone=None, tag=None, issue_date=None,
74
- curve_type=None, points=None, input_dict=None):
75
+
76
+ def __init__(
77
+ self, id=None, name=None, frequency=None, time_zone=None, tag=None, issue_date=None, curve_type=None, points=None, input_dict=None
78
+ ):
75
79
  self.id = id
76
80
  self.name = name
77
81
  self.frequency = frequency
@@ -89,19 +93,19 @@ class TS(object):
89
93
  if self.time_zone is not None:
90
94
  self.tz = parse_tz(self.time_zone)
91
95
  else:
92
- self.tz = ZoneInfo('CET')
96
+ self.tz = ZoneInfo("CET")
93
97
 
94
98
  if self.curve_type is None:
95
99
  self.curve_type = detect_curve_type(self.issue_date, self.tag)
96
100
  # Validation
97
101
  if self.frequency is None:
98
- raise CurveException('TS must have frequency')
102
+ raise CurveException("TS must have frequency")
99
103
 
100
104
  def __str__(self):
101
- size = ''
105
+ size = ""
102
106
  if self.points:
103
- size = ' size: {}'.format(len(self.points))
104
- return 'TS: {}{}'.format(self.fullname, size)
107
+ size = " size: {}".format(len(self.points))
108
+ return "TS: {}{}".format(self.fullname, size)
105
109
 
106
110
  @property
107
111
  def fullname(self):
@@ -116,10 +120,10 @@ class TS(object):
116
120
  attrs.append(self.tag)
117
121
  if self.issue_date:
118
122
  attrs.append(str(self.issue_date))
119
- return ' '.join(attrs)
123
+ return " ".join(attrs)
120
124
 
121
125
  def to_pandas(self, name=None):
122
- """ Converting :class:`volue_insight_timeseries.util.TS` object
126
+ """Converting :class:`volue_insight_timeseries.util.TS` object
123
127
  to a pandas.Series object
124
128
 
125
129
  Parameters
@@ -134,18 +138,32 @@ class TS(object):
134
138
  if name is None:
135
139
  name = self.fullname
136
140
  if self.points is None or len(self.points) == 0:
137
- return pd.Series(name=name, dtype='float64')
141
+ return pd.Series(name=name, dtype="float64")
138
142
 
139
143
  index = []
140
144
  values = []
141
145
  for row in self.points:
142
146
  if len(row) != 2:
143
- raise ValueError('Points have unexpected contents')
147
+ raise ValueError("Points have unexpected contents")
144
148
  dt = datetime.datetime.fromtimestamp(row[0] / 1000.0, self.tz)
145
149
  index.append(dt)
146
150
  values.append(row[1])
147
151
  res = pd.Series(name=name, index=index, data=values)
148
- return res.asfreq(self._map_freq(self.frequency))
152
+ mapped_freq = res.asfreq(self._map_freq(self.frequency))
153
+ dropped = mapped_freq.dropna()
154
+
155
+ # Warn about edge case for Gas Day timezone during DST changes.
156
+ # Gas Day is a 24-hour period starting at 4:00 UTC in summer and 5:00 UTC in winter,
157
+ # and finishing at 4:00 UTC (or 5:00) the next day. corresponding to 6:00 local time in Germany year-round.
158
+ # A gas loader bug causes timestamps on the day after DST to shift to 5:00 or 7:00 instead of 6:00.
159
+ if len(self.points) != len(dropped):
160
+ warnings.warn(
161
+ f"Data length mismatch: original data length is {len(self.points)}, but mapped frequency data length is "
162
+ f"{len(dropped)}. This may indicate data truncation.",
163
+ RuntimeWarning,
164
+ stacklevel=2,
165
+ )
166
+ return mapped_freq
149
167
 
150
168
  @staticmethod
151
169
  def from_pandas(pd_series):
@@ -183,7 +201,7 @@ class TS(object):
183
201
 
184
202
  @staticmethod
185
203
  def sum(ts_list, name):
186
- """ calculate the sum of a given list
204
+ """calculate the sum of a given list
187
205
  of :class:`volue_insight_timeseries.util.TS` objects
188
206
 
189
207
  Returns a :class:`~volue_insight_timeseries.util.TS`
@@ -205,7 +223,7 @@ class TS(object):
205
223
 
206
224
  @staticmethod
207
225
  def mean(ts_list, name):
208
- """ calculate the mean of a given list of TS objects
226
+ """calculate the mean of a given list of TS objects
209
227
 
210
228
  Returns a TS (:class:`volue_insight_timeseries.util.TS`) object that is
211
229
  the mean of a list of TS objects with the given name.
@@ -225,7 +243,7 @@ class TS(object):
225
243
 
226
244
  @staticmethod
227
245
  def median(ts_list, name):
228
- """ calculate the median of a given list of TS objects
246
+ """calculate the median of a given list of TS objects
229
247
 
230
248
  Returns a TS (:class:`volue_insight_timeseries.util.TS`) object that is
231
249
  the median of a list of TS objects with the given name.
@@ -297,10 +315,10 @@ def parserange(rangeobj, tz=None):
297
315
  """
298
316
  Parse a range object (a pair of date strings, which may each be None)
299
317
  """
300
- if rangeobj.get('empty') is True:
318
+ if rangeobj.get("empty") is True:
301
319
  return None
302
- begin = rangeobj.get('begin')
303
- end = rangeobj.get('end')
320
+ begin = rangeobj.get("begin")
321
+ end = rangeobj.get("end")
304
322
  if begin is not None:
305
323
  begin = parsetime(begin, tz=tz)
306
324
  if end is not None:
@@ -309,13 +327,13 @@ def parserange(rangeobj, tz=None):
309
327
 
310
328
 
311
329
  _tzmap = {
312
- 'CEGT': 'CET',
313
- 'WEGT': 'WET',
314
- 'PST': 'US/Pacific',
315
- 'TRT': 'Turkey',
316
- 'MSK': 'Europe/Moscow',
317
- 'ART': 'America/Argentina/Buenos_Aires',
318
- 'JST': 'Asia/Tokyo',
330
+ "CEGT": "CET",
331
+ "WEGT": "WET",
332
+ "PST": "US/Pacific",
333
+ "TRT": "Turkey",
334
+ "MSK": "Europe/Moscow",
335
+ "ART": "America/Argentina/Buenos_Aires",
336
+ "JST": "Asia/Tokyo",
319
337
  }
320
338
 
321
339
 
@@ -325,7 +343,7 @@ def parse_tz(time_zone):
325
343
  time_zone = _tzmap[time_zone]
326
344
  return ZoneInfo(time_zone)
327
345
  except ZoneInfoNotFoundError:
328
- return ZoneInfo('CET')
346
+ return ZoneInfo("CET")
329
347
 
330
348
 
331
349
  def detect_curve_type(issue_date, tag):
@@ -348,12 +366,12 @@ def is_integer(s):
348
366
 
349
367
 
350
368
  def make_arg(key, value):
351
- if hasattr(value, '__iter__') and not isinstance(value, basestring):
352
- return '&'.join([make_arg(key, v) for v in value])
369
+ if hasattr(value, "__iter__") and not isinstance(value, basestring):
370
+ return "&".join([make_arg(key, v) for v in value])
353
371
 
354
372
  if isinstance(value, datetime.date):
355
373
  tmp = value.isoformat()
356
374
  else:
357
- tmp = '{}'.format(value)
375
+ tmp = "{}".format(value)
358
376
  v = quote_plus(tmp)
359
- return '{}={}'.format(key, v)
377
+ return "{}={}".format(key, v)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: volue-insight-timeseries
3
- Version: 1.2.2
3
+ Version: 1.2.3
4
4
  Summary: Volue Insight API python library
5
5
  Home-page: https://www.volueinsight.com
6
6
  Author: Volue Insight