Skip to content

Commit

Permalink
Renamed tight/left include params to before_first and after_last
Browse files Browse the repository at this point in the history
- added examples using these params to docs
- updated old examples
- changed the behavior of tick when a single event is passed, the current behavior is more similar to the one before the new parameters
- fixed a bug on tick_calendar with a single element
- added tests for both operators testing the behavior for single-event inputs under different parameters
- added test for empty eventset on tick_calendar
- added changelog
  • Loading branch information
javiber committed Mar 18, 2024
1 parent dae235d commit a797c66
Show file tree
Hide file tree
Showing 9 changed files with 287 additions and 111 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@
### Improvements

- Speed up of calendar operations (now implemented in c++)
- Added `before_first` and `after_last` parameters to `EventSet.tick` and `EventSet.tick_calendar`

### Fixes

- Fixed a bug with `EventSet.tick_calendar` and daylight savings time.
- Fixed a bug in `EventSet.tick_calendar` where it would miss the first tick under certain conditions
- Fixed a bug in `EventSet.tick` where it would miss the last tick under certain conditions
- Fixed a bug with calendar operations and daylight savings time.

## 0.7.0
Expand Down
92 changes: 71 additions & 21 deletions temporian/core/event_set_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -4053,8 +4053,8 @@ def tick(
self: EventSetOrNode,
interval: Duration,
align: bool = True,
include_right: bool = True,
include_left: bool = False,
after_last: bool = True,
before_first: bool = False,
) -> EventSetOrNode:
"""Generates timestamps at regular intervals in the range of a guide
[`EventSet`][temporian.EventSet].
Expand All @@ -4065,7 +4065,7 @@ def tick(
>>> b = a.tick(interval=tp.duration.seconds(3), align=True)
>>> b
indexes: ...
timestamps: [ 6. 9. 12. 15.]
timestamps: [ 6. 9. 12. 15. 18.]
...
```
Expand All @@ -4076,19 +4076,40 @@ def tick(
>>> b = a.tick(interval=tp.duration.seconds(3), align=False)
>>> b
indexes: ...
timestamps: [ 5. 8. 11. 14.]
timestamps: [ 5. 8. 11. 14. 17.]
...
```
Example with before_first:
```python
>>> a = tp.event_set(timestamps=[5, 9, 16])
>>> b = a.tick(interval=tp.duration.seconds(3), align=True, before_first=True)
>>> b
indexes: ...
timestamps: [ 3. 6. 9. 12. 15. 18.]
...
```
Example without after_last:
```python
>>> a = tp.event_set(timestamps=[5, 9, 16])
>>> b = a.tick(interval=tp.duration.seconds(3), align=True, after_last=False)
>>> b
indexes: ...
timestamps: [ 6. 9. 12. 15.]
...
```
Args:
interval: Tick interval.
align: If false, the first tick is generated at the first timestamp
(similar to [`EventSet.begin()`][temporian.EventSet.begin]).
If true (default), ticks are generated on timestamps that are
multiple of `interval`.
include_right: If True, a tick after the last timestamp is included.
include_left: If True, a tick before the first timestamp is included.
after_last: If True, a tick after the last timestamp is included.
before_first: If True, a tick before the first timestamp is included.
Returns:
A feature-less EventSet with regular timestamps.
Expand All @@ -4099,8 +4120,8 @@ def tick(
self,
interval=interval,
align=align,
include_right=include_right,
include_left=include_left,
after_last=after_last,
before_first=before_first,
)

def tick_calendar(
Expand All @@ -4111,8 +4132,8 @@ def tick_calendar(
mday: Optional[Union[int, Literal["*"]]] = None,
month: Optional[Union[int, Literal["*"]]] = None,
wday: Optional[Union[int, Literal["*"]]] = None,
include_right: bool = True,
include_left: bool = False,
after_last: bool = True,
before_first: bool = False,
) -> EventSetOrNode:
"""Generates events periodically at fixed times or dates e.g. each month.
Expand Down Expand Up @@ -4142,7 +4163,7 @@ def tick_calendar(
>>> b
indexes: ...
events:
(365 events):
(366 events):
timestamps: [...]
...
Expand All @@ -4152,7 +4173,7 @@ def tick_calendar(
>>> tp.glue(b.calendar_hour(), b.calendar_minute())
indexes: ...
events:
(365 events):
(366 events):
timestamps: [...]
'calendar_hour': [2 2 2 ... 2 2 2]
'calendar_minute': [30 30 30 ... 30 30 30]
Expand All @@ -4164,7 +4185,7 @@ def tick_calendar(
>>> b.calendar_day_of_month()
indexes: ...
events:
(12 events):
(13 events):
timestamps: [...]
'calendar_day_of_month': [5 5 5 ... 5 5 5]
...
Expand All @@ -4176,10 +4197,10 @@ def tick_calendar(
>>> tp.glue(b.calendar_day_of_month(), b.calendar_month())
indexes: ...
events:
(2 events):
(3 events):
timestamps: [...]
'calendar_day_of_month': [1 1]
'calendar_month': [2 2]
'calendar_day_of_month': [1 1 1]
'calendar_month': [2 2 2]
...
>>> # Every second in the period (2 hours -> 7200 seconds)
Expand All @@ -4200,7 +4221,7 @@ def tick_calendar(
>>> b
indexes: ...
events:
(120 events):
(121 events):
timestamps: [...]
...
Expand All @@ -4211,6 +4232,30 @@ def tick_calendar(
ValueError: Can't set argument to None because previous and
following arguments were specified. Set to '*' or an integer ...
>>> # not after_last
>>> a = tp.event_set(timestamps=["2020-02-01", "2020-04-01"])
>>> b = a.tick_calendar(mday=10, after_last=False)
>>> tp.glue(b.calendar_day_of_month(), b.calendar_month())
indexes: ...
events:
(2 events):
timestamps: [...]
'calendar_day_of_month': [10 10]
'calendar_month': [2 3]
...
>>> # before_first
>>> a = tp.event_set(timestamps=["2020-02-01", "2020-04-01"])
>>> b = a.tick_calendar(mday=10, before_first=True)
>>> tp.glue(b.calendar_day_of_month(), b.calendar_month())
indexes: ...
events:
(4 events):
timestamps: [...]
'calendar_day_of_month': [10 10 10 10]
'calendar_month': [1 2 3 4]
...
```
Args:
Expand All @@ -4229,8 +4274,13 @@ def tick_calendar(
wday: '*' (any day), None (auto) or number in range `[0-6]`
(Sun-Sat) to tick at particular day of week. Can only be
specified if `day_of_month` is `None`.
include_right: If True, a tick after the last timestamp is included.
include_left: If True, a tick before the first timestamp is included.
after_last: If True, a tick after the last timestamp is included.
Useful for windows operations were you want the timestamps
to be included in the range of the ticks.
before_first: If True, a tick before the first timestamp is
included.
Useful for windows operations were you want the timestamps
to be included in the range of the ticks.
Returns:
A feature-less EventSet with timestamps at specified interval.
Expand All @@ -4245,8 +4295,8 @@ def tick_calendar(
mday=mday,
month=month,
wday=wday,
include_right=include_right,
include_left=include_left,
after_last=after_last,
before_first=before_first,
)

def timestamps(self: EventSetOrNode) -> EventSetOrNode:
Expand Down
Loading

0 comments on commit a797c66

Please sign in to comment.