pandas Cheatsheet

Dates and Time

Use this pandas reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Parsing Dates

import pandas as pd

# Parse a column to datetime
df["date"] = pd.to_datetime(df["date"])
df["date"] = pd.to_datetime(df["date"], format="%Y-%m-%d")       # explicit format (faster)
df["date"] = pd.to_datetime(df["date"], format="%d/%m/%Y")
df["date"] = pd.to_datetime(df["date"], errors="coerce")         # invalid → NaT
df["date"] = pd.to_datetime(df["date"], utc=True)                # localize to UTC
df["date"] = pd.to_datetime(df["date"], format="mixed")          # per-element inference

# Multiple columns → datetime
df["date"] = pd.to_datetime(df[["year", "month", "day"]])

# From Unix timestamps
pd.to_datetime(1_700_000_000, unit="s")   # seconds
pd.to_datetime(df["ts_ms"], unit="ms")    # milliseconds

# Read CSV and parse during load
df = pd.read_csv("data.csv", parse_dates=["date"])
# To combine year/month/day columns, parse after load:
df = pd.read_csv("data.csv")
df["date"] = pd.to_datetime(df[["year", "month", "day"]])

Legacy: parse_dates=[["year", "month", "day"]] (nested-list column combining) and infer_datetime_format=True were removed in pandas 3.0 — use the post-load pd.to_datetime patterns above.

Date Range Generation

pd.date_range("2024-01-01", "2024-12-31", freq="D")          # daily
pd.date_range("2024-01-01", periods=12, freq="ME")            # 12 month-ends
pd.date_range("2024-01-01", periods=4, freq="QE")             # 4 quarter-ends
pd.date_range("2024-01-01", periods=52, freq="W-MON")         # weekly, Mon
pd.date_range("09:00", "17:00", freq="h")                     # hourly
pd.date_range("2024-01-01", periods=24, freq="h", tz="UTC")   # timezone-aware

Common Frequency Aliases

AliasMeaning
"D"Calendar day
"B"Business day
"h"Hourly
"min"Minute
"s"Second
"ms"Millisecond
"us"Microsecond
"ns"Nanosecond
"W" / "W-MON"Weekly (Sunday / Monday anchor)
"ME"Month end
"MS"Month start
"QE"Quarter end
"QS"Quarter start
"YE"Year end
"YS"Year start (legacy alias "AS" deprecated in 2.2)
"BME"Business month end

.dt Accessor — Extract Date Components

s = df["date"]   # datetime64 Series

s.dt.year
s.dt.month           # 1–12
s.dt.day             # 1–31
s.dt.hour
s.dt.minute
s.dt.second
s.dt.microsecond
s.dt.nanosecond

s.dt.dayofweek       # 0=Monday … 6=Sunday
s.dt.day_name()      # "Monday", "Tuesday", …
s.dt.day_of_year     # 1–366
s.dt.isocalendar()   # DataFrame: year, week, day
s.dt.isocalendar().week  # ISO week number (dt.week was removed in 2.0)

s.dt.quarter         # 1–4
s.dt.days_in_month   # 28/29/30/31
s.dt.is_leap_year    # bool

s.dt.date            # Python date objects (object dtype)
s.dt.time            # Python time objects
s.dt.normalize()     # floor to midnight

s.dt.tz              # timezone info

.dt Rounding

s.dt.floor("h")       # round down to nearest hour
s.dt.ceil("min")      # round up to nearest minute
s.dt.round("D")       # round to nearest day

Timedeltas

# Create timedelta
td = pd.Timedelta("1 days")
td = pd.Timedelta(days=1, hours=6)
td = pd.to_timedelta(df["duration"], unit="s")   # from numeric

# Arithmetic
df["date"] + pd.Timedelta(days=7)
df["end"] - df["start"]               # returns Timedelta Series

# Timedelta components
td.days
td.seconds
td.total_seconds()

# timedelta_range
pd.timedelta_range("0 days", "7 days", freq="12h")

Timezone Handling

# Localize naive datetime to a timezone
s.dt.tz_localize("US/Eastern")
s.dt.tz_localize("UTC")
s.dt.tz_localize("America/New_York", ambiguous="NaT")   # DST ambiguity

# Convert between timezones
s.dt.tz_convert("US/Pacific")
s.dt.tz_convert("UTC")

# Remove timezone info
s.dt.tz_localize(None)

# pandas ≥ 2.0: use "UTC" aware timestamps by default to avoid performance warnings
df["date"] = pd.to_datetime(df["date"], utc=True)

Resampling Time Series

# DatetimeIndex required
df = df.set_index("date")

df.resample("ME").sum()             # monthly totals
df.resample("QE").mean()            # quarterly averages
df.resample("YE").agg({"sales": "sum", "price": "last"})
df.resample("W-MON").first()        # first value in each week
df["val"].resample("D").interpolate()  # resample + interpolate gaps

# Downsampling with custom origin
df.resample("ME", origin="start").sum()

Offset Objects and Business Days

from pandas.tseries.offsets import BDay, MonthEnd, YearEnd

today = pd.Timestamp("2024-06-15")
today + BDay(5)             # 5 business days later
today + MonthEnd(1)         # next month-end
today + YearEnd(0)          # current year-end (or next if already past)

# Business day range
pd.bdate_range("2024-01-01", "2024-01-31")

# Check if business day
pd.Timestamp("2024-06-15").isoweekday()   # 6 = Saturday

DatetimeIndex Operations

# Partial string indexing (when index is DatetimeIndex) — use .loc
df.loc["2024"]         # all of 2024
df.loc["2024-06"]      # all of June 2024
df["2024-06-01":"2024-06-30"]  # slice form still works with []

# truncate
df.truncate(before="2024-01-01", after="2024-06-30")

# shift
df.shift(1)            # shift values 1 period (freq-aware if DatetimeIndex)
df.shift(1, freq="ME") # shift index by 1 month-end

Period and PeriodIndex

p = pd.Period("2024-06", freq="M")   # Period freqs keep "M" — "ME" is only for offsets
p.start_time     # Timestamp
p.end_time       # Timestamp

pd.period_range("2024-01", "2024-12", freq="M")

# Convert between Timestamp and Period
s.dt.to_period("M")                   # Timestamp → Period (monthly)
s_period.dt.to_timestamp()            # Period → Timestamp

Common Gotchas

Timedelta arithmetic with object dtype fails — ensure the column is datetime64 first.

Partial string indexing (df.loc["2024"]) only works when the index is DatetimeIndex, not a regular column — and since pandas 2.0 it must go through .loc, not bare df["2024"].

freq="ME" (month end) replaced the old "M" alias for offsets/date_range in pandas 2.2 — but Period/to_period frequencies still use "M". Use "MS" for month start.

Mixed timezone DataFrames will fail on merge/concat — normalize to UTC first.