Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/whatsnew/v3.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1161,6 +1161,7 @@ Groupby/resample/rolling
- Bug in :meth:`.Resampler.interpolate` on a :class:`DataFrame` with non-uniform sampling and/or indices not aligning with the resulting resampled index would result in wrong interpolation (:issue:`21351`)
- Bug in :meth:`.Series.rolling` when used with a :class:`.BaseIndexer` subclass and computing min/max (:issue:`46726`)
- Bug in :meth:`DataFrame.ewm` and :meth:`Series.ewm` when passed ``times`` and aggregation functions other than mean (:issue:`51695`)
- Bug in :meth:`DataFrame.resample.asfreq` where fixed-frequency indexes with ``origin`` ignored alignment and returned incorrect values. Now ``origin`` and ``offset`` are respected. (:issue:`62725`)
- Bug in :meth:`DataFrame.resample` and :meth:`Series.resample` were not keeping the index name when the index had :class:`ArrowDtype` timestamp dtype (:issue:`61222`)
- Bug in :meth:`DataFrame.resample` changing index type to :class:`MultiIndex` when the dataframe is empty and using an upsample method (:issue:`55572`)
- Bug in :meth:`DataFrameGroupBy.agg` and :meth:`SeriesGroupBy.agg` that was returning numpy dtype values when input values are pyarrow dtype values, instead of returning pyarrow dtype values. (:issue:`53030`)
Expand Down
3 changes: 2 additions & 1 deletion pandas/core/resample.py
Original file line number Diff line number Diff line change
Expand Up @@ -2136,11 +2136,12 @@ def _upsample(self, method, limit: int | None = None, fill_value=None):
binner = self.binner
res_index = self._adjust_binner_for_upsample(binner)

# if we have the same frequency as our axis, then we are equal sampling
# if index exactly matches target grid (same freq & alignment), use fast path
if (
limit is None
and to_offset(ax.inferred_freq) == self.freq
and len(obj) == len(res_index)
and obj.index.equals(res_index)
):
result = obj.copy()
result.index = res_index
Expand Down
24 changes: 24 additions & 0 deletions pandas/tests/resample/test_resample_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -989,3 +989,27 @@ def test_resample_empty():
)
result = df.resample("8h").mean()
tm.assert_frame_equal(result, expected)


def test_asfreq_respects_origin_with_fixed_freq_all_seconds_equal():
# GH#62725: Ensure Resampler.asfreq respects origin="start_day"
# when all datetimes share identical seconds values.
idx = [
datetime(2025, 10, 17, 17, 15, 10),
datetime(2025, 10, 17, 17, 16, 10),
datetime(2025, 10, 17, 17, 17, 10),
]
df = DataFrame({"value": [0, 1, 2]}, index=idx)

result = df.resample("1min", origin="start_day").asfreq()

# Expected index: match dtype while preserving freq
exp_idx = pd.DatetimeIndex(
date_range("2025-10-17 17:15:00", periods=3, freq="min").astype(
result.index.dtype
),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you pass a list of Timestamps to the pd.DatetimeIndex constructor and pass the dtype as well? (For context, tests should minimize the use of extraneous APIs where possible.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, updated. Thanks

freq="min",
)

exp = DataFrame({"value": [np.nan, np.nan, np.nan]}, index=exp_idx)
tm.assert_frame_equal(result, exp)
Loading