A quick-reference cheat sheet of the most commonly used functions, organized by workflow stage. Written for use alongside SARIMAX / Chronos-2 / AutoGluon forecasting scripts.

1. Loading & Initial Inspection

pd.read_csv(path, parse_dates=['date_col'], index_col='date_col')
pd.read_excel(path, sheet_name=0, parse_dates=['date_col'])
df.info()                  # dtypes, nulls, memory
df.describe()               # summary stats
df.head() / df.tail()
df.shape
df.dtypes
df.columns.tolist()

Tip: Always parse dates on load with parse_dates= rather than converting after — avoids silent object-dtype dates that break resampling later.

2. Datetime Handling (core for TS work)

pd.to_datetime(df['date'], format='%Y-%m-%d', errors='coerce')
df.set_index('date', inplace=True)
df.index = pd.to_datetime(df.index)

df.sort_index(inplace=True)          # CRITICAL before any TS op
df.index.is_monotonic_increasing     # sanity check

# Extract components
df['year']    = df.index.year
df['month']   = df.index.month
df['dow']     = df.index.dayofweek
df['quarter'] = df.index.quarter
df['is_month_end'] = df.index.is_month_end

Common trap: df.sort_index() returns a copy by default — use inplace=True or reassign, otherwise your resample/diff operations run on unsorted data silently.

3. Missing Value Detection & Handling

df.isna().sum()                      # nulls per column
df.isna().mean() * 100               # % missing
df[df.isna().any(axis=1)]            # rows with any null

# Fill strategies (order matters for TS)
df.ffill()                           # forward fill — most common for TS
df.bfill()                           # backward fill
df.interpolate(method='linear')      # linear interpolation
df.interpolate(method='time')        # time-aware interpolation (uneven spacing)
df.fillna(df.mean())                 # mean imputation (use cautiously on TS)
df.dropna(subset=['target_col'])     # drop only if target is missing

For forecasting specifically: interpolate(method='time') is usually preferred over ffill() for continuous series (e.g. demand, price) because ffill creates artificial flat plateaus that can bias trend/seasonality estimation. Use ffill for step-like data (e.g. inventory status flags).

4. Duplicate & Consistency Checks

df.duplicated().sum()
df.drop_duplicates(subset=['date', 'sku'], keep='last')
df.index.duplicated().sum()          # duplicate timestamps — common TS bug
df[df.index.duplicated(keep=False)]  # inspect duplicate timestamp rows

TS-specific: duplicate index values will silently break resample() and asfreq(). Always check df.index.duplicated().sum() before resampling.

5. Resampling & Frequency Alignment

df.resample('D').sum()               # daily aggregation
df.resample('W').mean()
df.resample('M').agg({'sales':'sum','price':'mean'})
df.asfreq('D')                       # enforce frequency, introduces NaN for gaps
df.resample('D').asfreq()            # combine: regularize + expose gaps

pd.date_range(start, end, freq='D')  # build a complete calendar
df = df.reindex(pd.date_range(df.index.min(), df.index.max(), freq='D'))

Key workflow: reindex() against a full date_range is the standard way to expose missing dates in an otherwise irregular series — do this before deciding on an imputation strategy.

6. Outlier Detection

# Z-score method
from scipy import stats
z = np.abs(stats.zscore(df['value'].dropna()))
df[z > 3]

# IQR method
Q1, Q3 = df['value'].quantile([0.25, 0.75])
IQR = Q3 - Q1
mask = (df['value'] < Q1 - 1.5*IQR) | (df['value'] > Q3 + 1.5*IQR)
df[mask]

# Rolling window z-score (better for TS with trend/seasonality)
roll_mean = df['value'].rolling(30).mean()
roll_std  = df['value'].rolling(30).std()
df['is_outlier'] = np.abs(df['value'] - roll_mean) > 3 * roll_std

df['value_capped'] = df['value'].clip(lower=Q1-1.5*IQR, upper=Q3+1.5*IQR)

Note: static z-score/IQR assumes stationarity — for series with trend or seasonality, use a rolling window or detrend first (e.g. STL residuals) before flagging outliers.

7. Type Conversion & Cleaning

df['col'] = df['col'].astype('float64')
pd.to_numeric(df['col'], errors='coerce')   # coerce bad strings to NaN
df['col'] = df['col'].astype('category')    # for repeated string cols (SKU, region)
df['col'].str.strip().str.lower()           # whitespace/case normalization
df['col'].replace({'N/A': np.nan, '': np.nan})

8. Feature Engineering for Forecasting

# Lag features
df['lag_1']  = df['target'].shift(1)
df['lag_7']  = df['target'].shift(7)

# Rolling statistics
df['roll_mean_7']  = df['target'].rolling(7).mean()
df['roll_std_7']   = df['target'].rolling(7).std()
df['ewm_mean']     = df['target'].ewm(span=7).mean()

# Differencing (stationarity)
df['diff_1']  = df['target'].diff(1)
df['diff_7']  = df['target'].diff(7)          # seasonal diff
np.log1p(df['target'])                        # log transform (handles zeros)

# Pct change / growth
df['pct_change'] = df['target'].pct_change()

9. Grouping & Aggregation (multi-SKU / multi-series datasets)

df.groupby('sku')['qty'].transform('sum')
df.groupby(['sku', pd.Grouper(freq='M')])['qty'].sum()
df.pivot_table(index='date', columns='sku', values='qty', aggfunc='sum')
df.groupby('sku').apply(lambda g: g.set_index('date').resample('D').sum())

For panel/multi-series forecasting (Chronos-2, AutoGluon): pivot_table into a wide format is typically the fastest sanity check; long format (sku, date, value columns) is what AutoGluon’s TimeSeriesDataFrame expects.

10. NumPy Essentials Used Alongside Pandas

np.where(cond, val_if_true, val_if_false)
np.select([cond1, cond2], [val1, val2], default=val3)
np.nan
np.isnan(arr)
np.clip(arr, lower, upper)
np.log1p(arr) / np.expm1(arr)         # safe log/inverse for zero-inclusive data
np.array_split(arr, n)                # for CV folds
np.percentile(arr, [25, 75])
np.polyfit(x, y, deg=1)               # quick trend line

11. Quick Data Quality Checklist (run before modeling)

assert df.index.is_monotonic_increasing
assert not df.index.duplicated().any()
assert df.index.freq is not None or pd.infer_freq(df.index) is not None
print(df.isna().sum())
print(df.describe())
print(f"Date range: {df.index.min()} to {df.index.max()}")
print(f"Expected periods: {len(pd.date_range(df.index.min(), df.index.max(), freq='D'))}, Actual: {len(df)}")

Common Pitfalls Specific to TS Forecasting Prep

Pitfall Fix
Unsorted index breaks diff()/shift() silently sort_index() immediately after load
ffill() on continuous metrics creates fake flat trends Use interpolate(method='time') instead
Duplicate timestamps break resample() Check index.duplicated() before resampling
Static outlier thresholds flag seasonal peaks as anomalies Use rolling/detrended outlier detection
Mixing wide & long format between pandas prep and AutoGluon input Standardize on long format (item_id, timestamp, target) early
shift()/rolling() leaking future info in backtests Always compute features only on train-fold data in walk-forward CV