Pandas period_range(): Build Reporting Periods

Generate monthly, quarterly and weekly periods, name the index and build complete reporting calendars.

Generate the original monthly periods 🔝

pd.period_range() returns a PeriodIndex, not a DataFrame. Specify exactly two of start, end and periods. Period frequency M remains valid; timestamp month-end offsets use ME.
import pandas as pd
months = pd.period_range("2020-04-01", "2020-12-31", freq="M")
print(months)
assert len(months) == 9 and str(months[0]) == "2020-04"

Expected output

PeriodIndex(['2020-04', '2020-05', '2020-06', '2020-07', '2020-08', '2020-09',
             '2020-10', '2020-11', '2020-12'],
            dtype='period[M]')

Quarterly and weekly periods 🔝

Keep the original quarter and weekly examples. Weekly periods may extend beyond the supplied dates because the inputs select whole containing periods.
quarters = pd.period_range("2020-04-01", "2020-12-31", freq="Q")
weeks = pd.period_range("2020-04-01", "2020-04-30", freq="W")
print(quarters)
print(weeks)
assert quarters.astype(str).tolist() == ["2020Q2", "2020Q3", "2020Q4"]
assert weeks[0].start_time == pd.Timestamp("2020-03-30")

Expected output

PeriodIndex(['2020Q2', '2020Q3', '2020Q4'], dtype='period[Q-DEC]')
PeriodIndex(['2020-03-30/2020-04-05', '2020-04-06/2020-04-12',
             '2020-04-13/2020-04-19', '2020-04-20/2020-04-26',
             '2020-04-27/2020-05-03'],
            dtype='period[W-SUN]')

Business-day scheduling 🔝

The original business-day concept is retained using a business DatetimeIndex. Business-day Period support is deprecated in current Pandas. B skips weekends, not public holidays; a holiday-aware schedule needs a custom business calendar.
business = pd.bdate_range("2020-04-01", "2020-04-30")
print(business.strftime("%Y-%m-%d").tolist())
assert len(business) == 22 and (business.dayofweek < 5).all()

Expected output

['2020-04-01', '2020-04-02', '2020-04-03', '2020-04-06', '2020-04-07', '2020-04-08', '2020-04-09', '2020-04-10', '2020-04-13', '2020-04-14', '2020-04-15', '2020-04-16', '2020-04-17', '2020-04-20', '2020-04-21', '2020-04-22', '2020-04-23', '2020-04-24', '2020-04-27', '2020-04-28', '2020-04-29', '2020-04-30']

Specify periods and name 🔝

name labels the resulting index, not a DataFrame. Daily is the usual default for string endpoints; Period endpoints can supply their own frequency.
forward = pd.period_range("2020-04-20", periods=3, freq="M", name="report_month")
backward = pd.period_range(end="2020-06", periods=3, freq="M")
print(forward)
print("Index name:", forward.name)
assert forward.equals(backward)

Expected output

PeriodIndex(['2020-04', '2020-05', '2020-06'], dtype='period[M]', name='report_month')
Index name: report_month

Convert periods into boundary timestamps 🔝

Choose the start or end of each period explicitly. A period represents an interval, whereas a Timestamp represents a point in time.
print(forward.to_timestamp(how="start"))
print(forward.to_timestamp(how="end"))
assert forward[0].start_time == pd.Timestamp("2020-04-01")

Expected output

DatetimeIndex(['2020-04-01', '2020-05-01', '2020-06-01'], dtype='datetime64[us]', name='report_month', freq='MS')
DatetimeIndex(['2020-04-30 23:59:59.999999', '2020-05-31 23:59:59.999999',
               '2020-06-30 23:59:59.999999'],
              dtype='datetime64[us]', name='report_month', freq=None)

Build a complete monthly report 🔝

This synthetic workflow adds absent calendar months to a summary. Filling with zero is justified here only because the sample specification says absent months had no sales.
sales = pd.Series([10, 30], index=pd.PeriodIndex(["2020-04", "2020-06"], freq="M"))
calendar = pd.period_range("2020-04", "2020-06", freq="M")
report = sales.reindex(calendar, fill_value=0)
print(report)
assert report.tolist() == [10, 0, 30] and report.sum() == sales.sum()

Expected output

2020-04    10
2020-05     0
2020-06    30
Freq: M, dtype: int64

Common mistakes and parameter choices 🔝

Use pd.period_range(), not DataFrame.period_range(). start/end/periods require exactly two values. freq describes the period interval; name labels the index. Do not substitute ME or QE timestamp aliases for period M or Q. See date_range() for instants and resample() for aggregation.

Exercise: quarterly calendar 🔝

Generate four quarters starting 2026Q1, name the index quarter, and print their start timestamps. Try the Date and Time exercises next.

Exercise solution 🔝

Choose a period frequency explicitly.
answer = pd.period_range("2026Q1", periods=4, freq="Q", name="quarter")
print(answer)
print(answer.to_timestamp())
assert len(answer) == 4 and str(answer[-1]) == "2026Q4"

Expected output

PeriodIndex(['2026Q1', '2026Q2', '2026Q3', '2026Q4'], dtype='period[Q-DEC]', name='quarter')
DatetimeIndex(['2026-01-01', '2026-04-01', '2026-07-01', '2026-10-01'], dtype='datetime64[us]', name='quarter', freq='QS-OCT')

Practice in Google Colab 🔝

Open in Google Colab View on GitHub

Run examples in order, inspect formatted dates and try the exercise. Save a copy to keep edits.

Reference: Pandas period_range() documentation.




Subscribe to our YouTube Channel here



plus2net.com







Python Video Tutorials
Python SQLite Video Tutorials
Python MySQL Video Tutorials
Python Tkinter Video Tutorials
✖
We use cookies to improve your browsing experience. . Learn more
HTML MySQL PHP JavaScript ASP Photoshop Articles Contact us
© 2000-2026 plus2net.com All rights reserved worldwide Privacy Policy Disclaimer