-
-
Notifications
You must be signed in to change notification settings - Fork 19.3k
DOC/ENH: Holiday exclusion argument #61600
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DOC/ENH: Holiday exclusion argument #61600
Conversation
doc/source/whatsnew/v2.3.0.rst
Outdated
| - :meth:`Series.str.decode` result now has :class:`StringDtype` when ``future.infer_string`` is True (:issue:`60709`) | ||
| - :meth:`~Series.to_hdf` and :meth:`~DataFrame.to_hdf` now round-trip with :class:`StringDtype` (:issue:`60663`) | ||
| - Improved ``repr`` of :class:`.NumpyExtensionArray` to account for NEP51 (:issue:`61085`) | ||
| - The :class:`Holiday` has gained the constructor argument and field ``exclude_dates`` to exclude specific datetimes from a custom holiday calendar (:issue:`54382`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move this to v3.0.0.rst?
pandas/tseries/holiday.py
Outdated
| start_date=None, | ||
| end_date=None, | ||
| days_of_week: tuple | None = None, | ||
| exclude_dates: list[Any] | None = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| exclude_dates: list[Any] | None = None, | |
| exclude_dates: list[Timestamp] | None = None, |
Let's make the users do the Timestamp conversion before passing into this object
pandas/tseries/holiday.py
Outdated
| self.exclude_dates = ( | ||
| [Timestamp(ex) for ex in exclude_dates] | ||
| if exclude_dates is not None | ||
| else exclude_dates | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the constructor argument being stricter, we can just validate the arguments are all Timestamp
pandas/tseries/holiday.py
Outdated
| holiday_dates = DatetimeIndex( | ||
| [hd for hd in holiday_dates if hd not in self.exclude_dates] | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Conversion to
DatetimeIndexshould be done in__init__ - Probably better to use
.differenceor releated method instead
pandas/tseries/holiday.py
Outdated
| from typing import ( | ||
| TYPE_CHECKING, | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| from typing import ( | |
| TYPE_CHECKING, | |
| ) | |
| from typing import TYPE_CHECKING |
pandas/tseries/holiday.py
Outdated
| start_date=None, | ||
| end_date=None, | ||
| days_of_week: tuple | None = None, | ||
| exclude_dates: list[Timestamp] | None = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, can we type this as exclude_dates: DatetimeIndex | None = None,?
pandas/tseries/holiday.py
Outdated
| assert exclude_dates is None or all( | ||
| type(ex) == Timestamp for ex in exclude_dates | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you raise a ValueError if exclude_dates is not a DatetimeIndex or None?
| ) | ||
| self.end_date = Timestamp(end_date) if end_date is not None else end_date | ||
| self.observance = observance | ||
| assert days_of_week is None or type(days_of_week) == tuple |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I also switch this to throw a ValueError on failing? Or would that be a separate PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A separate PR would be better, thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this, should I open a new issue? Or just make another PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just another PR is fine
pandas/tseries/holiday.py
Outdated
| self.observance = observance | ||
| assert days_of_week is None or type(days_of_week) == tuple | ||
| self.days_of_week = days_of_week | ||
| if exclude_dates is not None and type(exclude_dates) != DatetimeIndex: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if exclude_dates is not None and type(exclude_dates) != DatetimeIndex: | |
| if not (exclude_dates is None or isinstance(exclude_dates, DatetimeIndex): |
|
I'm trying to figure out what the Pyodide test failing means, but struggling a bit. @mroeschke any insight in where I should look to resolve the failed check? Also trying to just rerun the checks, but couldn't figure out how to do that without making an empty commit |
| assert exclude.isin(original_dates).all() | ||
| assert ~exclude.isin(actual_dates).all() | ||
| assert actual_dates.isin(original_dates).all() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you construct the resulting DatetimeIndex and use tm.assert_index_equal i.e.
result = queens_jubilee_uk_spring_bank_holiday.dates(start, end)
expected = DatetimeIndex(...)
tm.assert_index_equal(result, expected)And below as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the tm.assert_index_equal() in addition to the above 3 asserts, hopefully that is okay? I can also delete the 3 assert statements from above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes could you delete the 3 assert statements in this test and below? Hardcoding the expected result and using tm.assert_index.equal is a stronger assertion than these statements
|
|
||
| original_dates = default_uk_spring_bank_holiday.dates(start, end) | ||
| actual_dates = queens_jubilee_uk_spring_bank_holiday.dates(start, end) | ||
| print(exclude.isin(original_dates).all()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| print(exclude.isin(original_dates).all()) |
I think that's unrelated to your PR, so no need to worry about it |
|
Thanks for all your help on the PR so far! I really appreciate it. Are there any other changes I should make? |
|
Thanks @sharkipelago |
Holidaydocumentation is missing or hard to find for re-arranged national holidays. #54382 (Replace xxxx with the GitHub issue number)doc/source/whatsnew/vX.X.X.rstfile if fixing a bug or adding a new feature.