Skip to content

BUG: pd.period_range ignores multiple of start frequency #47465

Closed
@jaheba

Description

@jaheba

Pandas version checks

  • I have checked that this issue has not already been reported.

  • I have confirmed this bug exists on the latest version of pandas.

  • I have confirmed this bug exists on the main branch of pandas.

Reproducible Example

import pandas as pd

start = pd.Period("2020", freq="3D")

a = pd.period_range(start, periods=2, freq=start.freq)
assert a[1] == start + 1

# Fails
b = pd.period_range(start, periods=2)
assert b[1] == start + 1

Issue Description

The issue lies in _get_ordinal_range:

def _get_ordinal_range(start, end, periods, freq, mult=1):
if com.count_not_none(start, end, periods) != 2:
raise ValueError(
"Of the three parameters: start, end, and periods, "
"exactly two must be specified"
)
if freq is not None:
freq = to_offset(freq)
mult = freq.n
if start is not None:
start = Period(start, freq)
if end is not None:
end = Period(end, freq)
is_start_per = isinstance(start, Period)
is_end_per = isinstance(end, Period)
if is_start_per and is_end_per and start.freq != end.freq:
raise ValueError("start and end must have same freq")
if start is NaT or end is NaT:
raise ValueError("start and end must not be NaT")
if freq is None:
if is_start_per:
freq = start.freq
elif is_end_per:
freq = end.freq
else: # pragma: no cover
raise ValueError("Could not infer freq from start/end")
if periods is not None:
periods = periods * mult
if start is None:
data = np.arange(
end.ordinal - periods + mult, end.ordinal + 1, mult, dtype=np.int64
)
else:
data = np.arange(
start.ordinal, start.ordinal + periods, mult, dtype=np.int64
)
else:
data = np.arange(start.ordinal, end.ordinal + 1, mult, dtype=np.int64)
return data, freq

A fix could be to replace:

if freq is None:
if is_start_per:
freq = start.freq
elif is_end_per:
freq = end.freq

with

   if freq is None:
        if is_start_per:
            freq = start.freq
            mult = freq.n
        elif is_end_per:
            freq = end.freq
            mult = freq.n

Expected Behavior

Omitting the freq argument of pd.period_range should be the same as passing the freq of the start or end field to it via freq=.

Installed Versions

Not relevant to issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions