Skip to content

Commit 23d141e

Browse files
authored
REF: move generate_range from offsets to the one place it is used (#34146)
1 parent aa3e611 commit 23d141e

File tree

3 files changed

+81
-93
lines changed

3 files changed

+81
-93
lines changed

pandas/core/arrays/datetimes.py

+79-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
import pandas.core.common as com
4949

5050
from pandas.tseries.frequencies import get_period_alias, to_offset
51-
from pandas.tseries.offsets import Day, Tick, generate_range
51+
from pandas.tseries.offsets import BDay, Day, Tick
5252

5353
_midnight = time(0, 0)
5454

@@ -2336,3 +2336,81 @@ def _maybe_localize_point(ts, is_none, is_not_none, freq, tz, ambiguous, nonexis
23362336
localize_args["tz"] = tz
23372337
ts = ts.tz_localize(**localize_args)
23382338
return ts
2339+
2340+
2341+
def generate_range(start=None, end=None, periods=None, offset=BDay()):
2342+
"""
2343+
Generates a sequence of dates corresponding to the specified time
2344+
offset. Similar to dateutil.rrule except uses pandas DateOffset
2345+
objects to represent time increments.
2346+
2347+
Parameters
2348+
----------
2349+
start : datetime, (default None)
2350+
end : datetime, (default None)
2351+
periods : int, (default None)
2352+
offset : DateOffset, (default BDay())
2353+
2354+
Notes
2355+
-----
2356+
* This method is faster for generating weekdays than dateutil.rrule
2357+
* At least two of (start, end, periods) must be specified.
2358+
* If both start and end are specified, the returned dates will
2359+
satisfy start <= date <= end.
2360+
2361+
Returns
2362+
-------
2363+
dates : generator object
2364+
"""
2365+
offset = to_offset(offset)
2366+
2367+
start = Timestamp(start)
2368+
start = start if start is not NaT else None
2369+
end = Timestamp(end)
2370+
end = end if end is not NaT else None
2371+
2372+
if start and not offset.is_on_offset(start):
2373+
start = offset.rollforward(start)
2374+
2375+
elif end and not offset.is_on_offset(end):
2376+
end = offset.rollback(end)
2377+
2378+
if periods is None and end < start and offset.n >= 0:
2379+
end = None
2380+
periods = 0
2381+
2382+
if end is None:
2383+
end = start + (periods - 1) * offset
2384+
2385+
if start is None:
2386+
start = end - (periods - 1) * offset
2387+
2388+
cur = start
2389+
if offset.n >= 0:
2390+
while cur <= end:
2391+
yield cur
2392+
2393+
if cur == end:
2394+
# GH#24252 avoid overflows by not performing the addition
2395+
# in offset.apply unless we have to
2396+
break
2397+
2398+
# faster than cur + offset
2399+
next_date = offset.apply(cur)
2400+
if next_date <= cur:
2401+
raise ValueError(f"Offset {offset} did not increment date")
2402+
cur = next_date
2403+
else:
2404+
while cur >= end:
2405+
yield cur
2406+
2407+
if cur == end:
2408+
# GH#24252 avoid overflows by not performing the addition
2409+
# in offset.apply unless we have to
2410+
break
2411+
2412+
# faster than cur + offset
2413+
next_date = offset.apply(cur)
2414+
if next_date >= cur:
2415+
raise ValueError(f"Offset {offset} did not decrement date")
2416+
cur = next_date

pandas/tests/indexes/datetimes/test_date_range.py

+2-8
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,9 @@
1616
import pandas as pd
1717
from pandas import DatetimeIndex, Timestamp, bdate_range, date_range, offsets
1818
import pandas._testing as tm
19+
from pandas.core.arrays.datetimes import generate_range
1920

20-
from pandas.tseries.offsets import (
21-
BDay,
22-
CDay,
23-
DateOffset,
24-
MonthEnd,
25-
generate_range,
26-
prefix_mapping,
27-
)
21+
from pandas.tseries.offsets import BDay, CDay, DateOffset, MonthEnd, prefix_mapping
2822

2923
START, END = datetime(2009, 1, 1), datetime(2010, 1, 1)
3024

pandas/tseries/offsets.py

-84
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import numpy as np
77

88
from pandas._libs.tslibs import (
9-
NaT,
109
Period,
1110
Timedelta,
1211
Timestamp,
@@ -2305,89 +2304,6 @@ class Nano(Tick):
23052304
CBMonthBegin = CustomBusinessMonthBegin
23062305
CDay = CustomBusinessDay
23072306

2308-
# ---------------------------------------------------------------------
2309-
2310-
2311-
def generate_range(start=None, end=None, periods=None, offset=BDay()):
2312-
"""
2313-
Generates a sequence of dates corresponding to the specified time
2314-
offset. Similar to dateutil.rrule except uses pandas DateOffset
2315-
objects to represent time increments.
2316-
2317-
Parameters
2318-
----------
2319-
start : datetime, (default None)
2320-
end : datetime, (default None)
2321-
periods : int, (default None)
2322-
offset : DateOffset, (default BDay())
2323-
2324-
Notes
2325-
-----
2326-
* This method is faster for generating weekdays than dateutil.rrule
2327-
* At least two of (start, end, periods) must be specified.
2328-
* If both start and end are specified, the returned dates will
2329-
satisfy start <= date <= end.
2330-
2331-
Returns
2332-
-------
2333-
dates : generator object
2334-
"""
2335-
from pandas.tseries.frequencies import to_offset
2336-
2337-
offset = to_offset(offset)
2338-
2339-
start = Timestamp(start)
2340-
start = start if start is not NaT else None
2341-
end = Timestamp(end)
2342-
end = end if end is not NaT else None
2343-
2344-
if start and not offset.is_on_offset(start):
2345-
start = offset.rollforward(start)
2346-
2347-
elif end and not offset.is_on_offset(end):
2348-
end = offset.rollback(end)
2349-
2350-
if periods is None and end < start and offset.n >= 0:
2351-
end = None
2352-
periods = 0
2353-
2354-
if end is None:
2355-
end = start + (periods - 1) * offset
2356-
2357-
if start is None:
2358-
start = end - (periods - 1) * offset
2359-
2360-
cur = start
2361-
if offset.n >= 0:
2362-
while cur <= end:
2363-
yield cur
2364-
2365-
if cur == end:
2366-
# GH#24252 avoid overflows by not performing the addition
2367-
# in offset.apply unless we have to
2368-
break
2369-
2370-
# faster than cur + offset
2371-
next_date = offset.apply(cur)
2372-
if next_date <= cur:
2373-
raise ValueError(f"Offset {offset} did not increment date")
2374-
cur = next_date
2375-
else:
2376-
while cur >= end:
2377-
yield cur
2378-
2379-
if cur == end:
2380-
# GH#24252 avoid overflows by not performing the addition
2381-
# in offset.apply unless we have to
2382-
break
2383-
2384-
# faster than cur + offset
2385-
next_date = offset.apply(cur)
2386-
if next_date >= cur:
2387-
raise ValueError(f"Offset {offset} did not decrement date")
2388-
cur = next_date
2389-
2390-
23912307
prefix_mapping = {
23922308
offset._prefix: offset
23932309
for offset in [

0 commit comments

Comments
 (0)