Slicing by dates is one of the most common and powerful operations when working with time-series data in pandas. Once a date column is set as the index (and preferably sorted), you can slice ranges using label-based syntax with .loc[start:end] — just like slicing strings or lists, but with datetime awareness.
In 2026, this pattern remains essential for filtering historical data, backtesting models, reporting periods, or analyzing trends over specific windows. Here’s a practical guide with real examples you can copy and adapt.
1. Setup: Create and Prepare Time-Series Data
import pandas as pd
# Create sample daily data
dates = pd.date_range(start='2022-01-01', end='2022-01-10', freq='D')
df = pd.DataFrame({'value': range(10)}, index=dates)
# Ensure index is datetime and sorted (best practice)
df = df.sort_index()
print(df.head())
Output (first few rows):
value
2022-01-01 0
2022-01-02 1
2022-01-03 2
2022-01-04 3
2022-01-05 4
2. Basic Date Range Slicing with .loc[]
Slice using string dates (pandas parses them automatically) or datetime objects.
start_date = '2022-01-03'
end_date = '2022-01-07'
sliced = df.loc[start_date:end_date]
print(sliced)
Output (inclusive range):
value
2022-01-03 2
2022-01-04 3
2022-01-05 4
2022-01-06 5
2022-01-07 6
3. More Flexible Slicing Techniques
Using datetime objects (more robust)
from datetime import datetime
start_dt = datetime(2022, 1, 3)
end_dt = datetime(2022, 1, 7)
sliced_dt = df.loc[start_dt:end_dt]
Partial dates (pandas fills missing parts)
# All of January 2022
jan_2022 = df.loc['2022-01']
# From Jan 5 to end of month
mid_to_end = df.loc['2022-01-05':'2022-01-31']
Exclusive end (use .iloc or adjust dates)
# Up to but not including Jan 7
up_to_6 = df.loc[:'2022-01-06'] # inclusive end by default
4. Real-World Use Cases (2026 Examples)
Filter recent data for reporting
recent = df.loc['2025-12-01':] # from Dec 1, 2025 to latest
monthly_summary = recent.resample('M').sum()
Backtest trading strategy over period
backtest_period = df.loc['2024-01-01':'2024-12-31']
signals = backtest_period['close'] > backtest_period['close'].rolling(20).mean()
Compare Q1 across years
q1_all_years = df.loc[(df.index.month <= 3)]
5. Modern Alternative in 2026: Polars
For large time-series datasets, Polars is often faster and more memory-efficient — slicing syntax is very similar.
import polars as pl
df_pl = pl.DataFrame({
'date': pl.date_range(
start=pl.date(2022, 1, 1),
end=pl.date(2022, 1, 10),
interval='1d'
),
'value': range(10)
}).set_sorted('date')
sliced_pl = df_pl.filter(
(pl.col('date') >= pl.date(2022, 1, 3)) &
(pl.col('date') <= pl.date(2022, 1, 7))
)
print(sliced_pl)
Best Practices & Common Pitfalls
- Always sort the index first:
df = df.sort_index()— required for label range slicing - Both start and end are inclusive — unlike normal Python slicing
- Use string dates or datetime objects — pandas parses intelligently
- Check index type:
df.index.dtypeshould be datetime64[ns] - For partial dates, pandas fills missing parts (e.g., '2022-01' ? full month)
- For huge data, prefer Polars filtering — it's faster and more memory-efficient
Conclusion
Slicing by dates with .loc[start:end] is the cleanest way to filter time-series data in pandas — fast, intuitive, and inclusive on both ends. In 2026, always sort your datetime index first, use explicit datetime objects when precision matters, and reach for Polars when performance is critical. Master date string parsing, inclusive slicing, and index sorting, and you'll confidently extract any time window for analysis, reporting, or modeling.
Next time you need data for a specific period — slice by dates with .loc first.