Skip to content

Commit

Permalink
BUG/CLN - offsets.Day(n>2) not properly anchoring dates, and make cod…
Browse files Browse the repository at this point in the history
…e more readable
  • Loading branch information
Artin Sarraf committed Dec 7, 2018
1 parent 47d7f7b commit eb05501
Showing 1 changed file with 28 additions and 43 deletions.
71 changes: 28 additions & 43 deletions pandas/core/resample.py
Original file line number Diff line number Diff line change
Expand Up @@ -1546,30 +1546,24 @@ def _get_period_bins(self, ax):
end = ax.max().asfreq(self.freq, how='end')
offset = 0

# GH 23882
if self.base:
start = start.to_timestamp()
end = end.to_timestamp()

# get base adjusted bin edge labels
p_start, p_end = _get_range_edges(start,
end,
self.freq,
closed=self.closed,
base=self.base,
compensate_edges=True)

labels = binner = PeriodIndex(start=p_start, end=p_end,
freq=self.freq,
name=ax.name)
p_start, end = _get_range_edges(start,
end,
self.freq,
closed=self.closed,
base=self.base)

# Get offset for bin edge (not label edge) adjustment
start_offset = (pd.Period(start, self.freq)
- pd.Period(p_start, self.freq))
# remove /freq_mult once period diff scaling bug is fixed
offset = int(start_offset.n / freq_mult) % freq_mult
else:
labels = binner = PeriodIndex(start=start, end=end,
freq=self.freq, name=ax.name)
start = p_start

labels = binner = PeriodIndex(start=start, end=end,
freq=self.freq, name=ax.name)

i8 = memb.asi8

Expand Down Expand Up @@ -1608,18 +1602,27 @@ def _take_new_index(obj, indexer, new_index, axis=0):
raise ValueError("'obj' should be either a Series or a DataFrame")


def _get_range_edges(first, last, offset, closed='left', base=0,
compensate_edges=False):
first_ = first
last_ = last
def _get_range_edges(first, last, offset, closed='left', base=0):
if type(first) != type(last):
raise TypeError("'first' and 'last' must be same type")

# make proper adjustments for Periods #GH 23882
is_period = False
adjust_first = adjust_last = False
if isinstance(first, pd.Period):
is_period = True
first = first.to_timestamp()
last = last.to_timestamp()
adjust_first = not offset.onOffset(first)
adjust_last = offset.onOffset(last)

additional_adjust = True
if isinstance(offset, Tick):
is_day = isinstance(offset, Day)
day_nanos = delta_to_nanoseconds(timedelta(1))

# #1165
if (is_day and day_nanos % offset.nanos == 0) or not is_day:
# #1165 / #24127
if (is_day and not offset.nanos % day_nanos) or not is_day:
additional_adjust = False
# Don't return immediately because might need to compensate edges
first, last = _adjust_dates_anchored(first, last, offset,
Expand All @@ -1637,27 +1640,9 @@ def _get_range_edges(first, last, offset, closed='left', base=0,

last = Timestamp(last + offset)

if compensate_edges:
first, last = _compensate_edges(first, last, first_, last_, offset)

return first, last


def _compensate_edges(adj_first, adj_last, orig_first, orig_last, offset):
# Implement this function in expanded form, instead of the shorter form
# to ensure that all these cases are covered in code coverage reports

# first = adj_first + offset * (not offset.onOffset(orig_first))
if not offset.onOffset(orig_first):
first = adj_first + offset
else:
first = adj_first

# last = adj_last - offset * offset.onOffset(orig_last)
if offset.onOffset(orig_last):
last = adj_last - offset
else:
last = adj_last
if is_period:
first = (first + adjust_first * offset).to_period(offset)
last = (last - adjust_last * offset).to_period(offset)

return first, last

Expand Down

0 comments on commit eb05501

Please sign in to comment.