Written and maintained by CASRAI Editorial Board
Published
On this page
The pandas resample method provides frequency conversion and time-bucket aggregation for time series data. In research workflows, datasets collected from physical sensors, clinical monitoring equipment, environmental logging arrays, or automated laboratory assays frequently record observations at uneven timestamps or at higher sampling rates than required for statistical modeling. Using resample pandas workflows allows analysts to downsample high-frequency measurements into standardized intervals or upsample low-frequency data to align multiple instruments onto a shared temporal grid.
What it is used for in research
In observational and experimental research, time series datasets often present irregular intervals, variable sampling rates across instruments, or sensor noise that obscures underlying trends. The DataFrame.resample() and Series.resample() methods serve several core functions in research data preparation:
- Downsampling and Aggregation: Condensing high-frequency continuous telemetry (such as 10 Hz accelerometer readings or 1-minute weather station logs) into hourly, daily, or weekly summaries using statistical estimators such as mean, standard deviation, median, or interquartile ranges.
- Temporal Standardization: Aligning asynchronous measurements from disparate instruments onto uniform time buckets so multi-stream data can be merged and analyzed jointly.
- Upsampling and Gap Imputation: Expanding low-frequency records (such as weekly laboratory specimen counts or monthly field surveys) onto daily grids using forward-filling, backward-filling, or linear interpolation.
- Multi-Variable Summaries: Applying composite aggregations across complex data structures, such as calculating simultaneous minimum, maximum, mean, and sample counts across experimental channels.
Resampling requires the target DataFrame or Series to have a datetime-like index (such as a DatetimeIndex, TimedeltaIndex, or PeriodIndex) or to specify a datetime column directly using the on parameter. For related details on preparing timestamp columns and validating data structures, refer to the guides on pandas datetime parsing and pandas dtypes management.
Install or access (official source only)
The pandas library is open-source software distributed under the BSD 3-Clause License. It can be installed into research environments directly through official Python package repositories:
- PyPI (Python Package Index):
pip install pandas - Conda (conda-forge channel):
conda install -c conda-forge pandas
Official pandas releases require Python 3.10 or higher. Researchers can verify the installed version and import the package in an interactive shell or script:
import pandas as pd
print(pd.__version__)
Step-by-step task (numbered, with menu names or commands exactly as in the current docs)
The following five-step task demonstrates how to construct a research time series, downsample it to regular intervals, control bin boundary behaviors, upsample with interpolation, and resample directly on a DataFrame column without resetting the index.
Step 1: Construct a sample research time series with DatetimeIndex
Generate a sample environmental monitoring dataset with 10-minute intervals over a 24-hour observation window:
import pandas as pd
import numpy as np
# Create datetime index spanning 24 hours at 10-minute intervals
timestamps = pd.date_range(start="2026-05-01 00:00:00", periods=144, freq="10min")
# Generate synthetic sensor data for temperature and relative humidity
np.random.seed(42)
df_sensor = pd.DataFrame({
"temperature_c": np.random.normal(loc=21.5, scale=1.2, size=144),
"humidity_pct": np.random.normal(loc=55.0, scale=3.5, size=144)
}, index=timestamps)
print(df_sensor.head(3))
Step 2: Downsample observations using modern offset aliases
To reduce 10-minute sensor data to 1-hour summary statistics, pass the frequency string 'h' to .resample() and apply an aggregation function such as .mean() or .agg(). Note that in pandas 2.2 and newer, legacy frequency aliases like 'H', 'M', and 'T' are deprecated in favor of lowercase 'h', month-end 'ME', and 'min'.
# Downsample to hourly mean values
hourly_means = df_sensor.resample("h").mean()
# Calculate multiple summary statistics simultaneously across channels
hourly_summary = df_sensor.resample("h").agg({
"temperature_c": ["mean", "min", "max", "std"],
"humidity_pct": ["mean", "std"]
})
print(hourly_summary.head(3))
Step 3: Control bin edges and labeling with closed, label, and origin
By default, sub-daily frequencies like 'h' or '15min' align intervals to midnight (origin='start_day') with the interval closed on the left (closed='left') and labeled using the left edge (label='left'). In an interval [10:00, 11:00), a measurement at exactly 10:00 is included, while a measurement at 11:00 falls into the next bin.
To include the right boundary in the interval and label each bin with its ending timestamp, configure closed='right' and label='right':
# Resample into 2-hour buckets closed and labeled on the right
hourly_right = df_sensor.resample("2h", closed="right", label="right").mean()
# Align intervals to the earliest timestamp in the data rather than midnight
hourly_start_aligned = df_sensor.resample("2h", origin="start").mean()
Step 4: Upsample low-frequency records and interpolate missing intervals
When aligning lower-frequency measurements to higher-frequency recording intervals (upsampling), pandas creates new timestamp buckets containing missing values (NaN). To impute these values, chain filling or interpolation methods:
# Sample daily aggregated metrics
daily_df = df_sensor.resample("D").mean()
# Upsample from daily to 6-hour intervals with forward-fill
upsampled_ffill = daily_df.resample("6h").ffill()
# Upsample from daily to 6-hour intervals using linear interpolation
upsampled_interp = daily_df.resample("6h").interpolate(method="linear")
print(upsampled_interp.head(4))
For mathematical background on piecewise polynomial and spline fitting in scientific programming, consult the guide on MATLAB interpolation.
Step 5: Resample without altering the primary DataFrame index
If your DataFrame uses a non-temporal index (such as participant IDs or specimen barcodes), you can pass the timestamp column name to the on parameter without calling set_index():
# Reset index to illustrate non-indexed timestamp columns
df_flat = df_sensor.reset_index().rename(columns={"index": "recorded_at"})
# Resample directly using the 'on' argument
resampled_col = df_flat.resample("3h", on="recorded_at").mean()
print(resampled_col.head(2))
Output and how to read it
Executing df.resample(rule) does not immediately compute values. Instead, it returns a Resampler object (specifically an instance of pandas.core.resample.DatetimeIndexResampler). This object acts as a deferred groupby mechanism waiting for an aggregation or transformation method.
When an aggregation method like .mean(), .sum(), or .agg() is evaluated, the resulting object exhibits the following characteristics:
- Resulting Index: The output index is a
DatetimeIndexwhose frequency attribute (freq) reflects the target rule string (such as<Hour>or<Day>). - Bucket Timestamps: Each index value corresponds to the interval bin label determined by the
labelandoriginsettings. Whenlabel='left'is active, timestamp2026-05-01 01:00:00represents the interval spanning from 01:00:00 up to (but not including) 02:00:00. - Empty Bins: If no raw observations fall within a specific temporal window, aggregation methods return
NaNfor continuous measures and 0 for count methods like.count(). - Multi-Level Columns: When applying dictionaries or lists of aggregation functions via
.agg(), pandas returns a DataFrame with a two-level hierarchical column index containing the original field names at level 0 and the applied metric names at level 1.
Troubleshooting
Researchers commonly encounter several predictable exceptions and data anomalies when resampling time series in pandas. The table below lists these issues, their underlying causes, and direct solutions:
| Observed Issue or Exception | Root Cause | Corrective Action |
|---|---|---|
TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex |
The DataFrame index consists of integers, strings, or floats, and the on parameter was not specified. |
Convert the date column using df['timestamp'] = pd.to_datetime(df['timestamp']) and either set it as the index with df.set_index('timestamp') or pass on='timestamp' to .resample(). |
FutureWarning: 'H' is deprecated and will be removed in a future version |
Use of legacy pandas 1.x uppercase frequency aliases ('H', 'M', 'T', 'S'). |
Update frequency strings to modern pandas 2.2+ standards: use 'h' for hours, 'min' for minutes, 's' for seconds, and 'ME' for month-end. |
| Unexpected bin alignment (e.g., intervals offset by minutes or hours) | Default origin='start_day' anchors bins to midnight (00:00:00), which can fragment irregular logging windows. |
Explicitly set origin='start' to anchor intervals to the first timestamp, or provide an explicit timestamp string like origin='2026-05-01 08:00:00'. |
| Upsampled DataFrame contains entirely NaN values | Calling an aggregation function like .mean() on an upsampled series with non-overlapping new bins. |
Use filling or interpolation methods such as .ffill(), .bfill(), or .interpolate(method='linear') rather than simple reductions. |
Free alternatives (table)
While pandas is standard in Python scientific computing, alternative open-source software libraries provide time series resampling capabilities across different languages and computing architectures:
| Tool / Package | Language / Ecosystem | Core Resampling Function | Key Strengths in Research | Primary Use Case |
|---|---|---|---|---|
| Polars | Python / Rust | group_by_dynamic(), upsample() |
Parallelized Rust core, memory-efficient streaming, zero-copy operations on large datasets. | High-throughput laboratory sensor arrays exceeding system memory; see Polars vs pandas. |
| R (xts / zoo) | R / CRAN | period.apply(), to.period(), aggregate.zoo() |
Extensive econometric and biostatistical test suites; seamless integration with base R time series. | Clinical trials and biometric research centered in the R statistical environment. |
| DuckDB | SQL / In-process OLAP | time_bucket(), date_trunc() |
Direct query execution over large Parquet and CSV files without memory overhead. | Pre-aggregating multi-gigabyte observational logs before downstream analysis. |
| TimeSeries.jl | Julia | collapse() |
High mathematical performance and native support for continuous scientific computing models. | Physics, geophysical simulations, and dynamic systems modeling. |
FAQ
What is the difference between pandas resample and groupby?
Both methods perform split-apply-combine operations. However, groupby() requires exact matching of discrete values (such as categories or distinct dates), whereas resample() groups continuous temporal data into predefined time intervals (bins) based on calendar or clock frequencies, handling edge boundaries and missing intervals automatically.
How do you fix the FutureWarning for ‘H’ and ‘M’ in pandas resample?
In pandas 2.2 and later, uppercase aliases for hours ('H') and months ('M') are deprecated. Replace 'H' with lowercase 'h' for hourly frequency, 'M' with 'ME' for month-end frequency, and 'T' with 'min' for minute frequency.
Does pandas resample modify the DataFrame in place?
No. resample() never modifies the original DataFrame or Series in place. It produces a deferred Resampler object, and applying an aggregation or filling method yields a newly constructed DataFrame.
How do closed and label differ in pandas resample?
The closed parameter dictates which boundary of the time bin includes the boundary timestamp (e.g., closed='left' means [start, end)). The label parameter dictates which boundary timestamp is assigned to the output index row (e.g., label='left' uses the starting timestamp of the bin).
Sources (official docs)
- pandas development team. (2026). pandas.DataFrame.resample API reference. Official documentation. https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.resample.html (read 2026-11-09).
- pandas development team. (2026). Time Series / Date Functionality: Resampling. pandas User Guide. https://pandas.pydata.org/docs/user_guide/timeseries.html#resampling (read 2026-11-09).
- Python Software Foundation / PyPI. (2026). pandas: powerful Python data analysis toolkit. PyPI project repository. https://pypi.org/pypi/pandas/json (read 2026-11-09).







