-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
BUG: Cannot add non-vectorized DateOffset to empty DatetimeIndex #12724
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
Comments
Currently, I'm using the following patch as a temporarily workaround. The workaround is to simply return the index if the length is 0, which should be ok as the index is immutable. def _add_offset(self, offset):
import warnings
try:
from pandas.io.common import PerformanceWarning
except:
from pandas.core.common import PerformanceWarning
try:
if self.tz is not None:
values = self.tz_localize(None)
else:
values = self
result = offset.apply_index(values)
if self.tz is not None:
result = result.tz_localize(self.tz)
return result
except NotImplementedError:
warnings.warn("Non-vectorized DateOffset being applied to Series "
"or DatetimeIndex", PerformanceWarning)
if len(self) == 0:
return self
return self.astype('O') + offset
def patch_pandas_index():
pd.DatetimeIndex._add_offset = _add_offset
# Patch pandas empty datetimeindex and offset operations
patch_pandas_index() |
not really sure this is supported, meaning this kind of |
This definitely used to be a supported feature, as least in 0.16.x The custom MLK rule in my testcase is simply a modified example taken from tseries/holiday.py. The holiday.py module is shipped with pandas and it uses dateutil.relativedelta, so it must be a supported feature. USMartinLutherKingJr = Holiday('Dr. Martin Luther King Jr.', start_date=datetime(1986,1,1), month=1, day=1,
offset=DateOffset(weekday=MO(3))) This kind of holiday rule is quite common for exchanges across the world, e.g. as new national holidays introduced they would all have a start date. With this bug generating holidays before the starting date would not be possible. one would simply expect an empty index returned if rule does not yield any holidays. |
hmm, maybe something broke. Though the [19] is expected to be honest, its not really clear what to do with this. you are trying to add a frequency aware object to something with no frequency, so what should you do? coerce or raise? I think this error message is fine, maybe something needs an adjustment in the holiday logic.
|
in [19], I think the expected output should be:
i.e. the same index as before. I think that was the behaviour in pandas 0.16.x (I haven't had time to check) I think the behaviour for empty DateTimeIndex should be consistent with other empty indexes, as well as empty numpy arrays.
|
It is probably easier to fix this within the holiday.py module, maybe DatetimeIndex should be special. |
@yerikzheng that example is not the same. Those don't have frequencies, so datetimelikes ARE special. Adding a frequency aware object to a non-freq aware is an explicit error. |
Yes, thinking about it again I agree with you. However, I do expect AbstractHolidayCalendar.holidays() method to handle the case for which no holiday is generated by the rule, so this must have broke since 0.17.0 release as it did work correctly before. |
@yerikzheng would love for a PR for this. |
Funny that I just came across this post. I found this error today with the same exact issue (MLK for start of 1998). I have begun looking into a work around but this definitely used to be supported. It should be fixed in the next release. |
This looks fixed on master (Jeff's example). Guess this could use a test
|
After the holidays refactor in pandas 0.17.0+, I'm seeing errors when calling the AbstractHolidayCalendar.holidays() method with a date range that is before the declared Holiday rule. Consider the example below, I'm declaring a custom MLK holiday for CME equities market with a specific start date of 1998-01-01, with a non-vectorised DateOffset (third monday of January).
If I call calendar.holidays(start='2015-01-01', end='2015-12-31'), it blows up with an exception:
After some digging, it appears that if the supplied date range is a year before the declared holiday rule start date, the DatetimeIndex constructed in tseries/holiday.py is an empty index (a reasonable optimization), but when a non-vectorized DateOffset is being applied to an empty DatetimeIndex, the _add_offset method in tseries/index.py returns a plain empty Index, rather than DatetimeIndex, on which .asi8 is subsequently called and returns None instead of an empty numpy i8 array.
So the underlying problem is that an empty DatetimeIndex doesn't like a non-vectorized DateOffset applied to it.
Observe the testcase below, which reproduces the issue.
Test case
Output
The following tests fail:
output of
pd.show_versions()
The text was updated successfully, but these errors were encountered: