Cumulative Sum in Pandas – cumsum(), cummax(), cummin() & More in Python 2026

Data Manipulation Mar 18, 2026

Cumulative Sum in Pandas – cumsum(), cummax(), cummin() & More in Python 2026

Cumulative calculations are extremely useful in data manipulation for running totals, growth analysis, ranking over time, and creating useful features. In 2026, Pandas provides fast and flexible cumulative functions like cumsum(), cummax(), cummin(), and cumprod().

TL;DR — Key Cumulative Methods

  • .cumsum() – Running total
  • .cummax() – Running maximum
  • .cummin() – Running minimum
  • .cumprod() – Running product
  • .cummax() / .cummin() with groupby() for segmented analysis

1. Basic Cumulative Sum

import pandas as pd

# Create a small demo file so this example runs as-is
# (in your project, sales_data.csv is your real export)
import numpy as np
rng = np.random.default_rng(42)
n = 60
pd.DataFrame({
    "order_date": pd.date_range("2025-10-01", periods=n, freq="3D"),
    "customer_id": rng.integers(101, 121, n),
    "customer_name": rng.choice([" ana", "ben ", "chen", "dana"], n),
    "product_id": rng.integers(1, 9, n),
    "region": rng.choice(["North", "South", "East", "West"], n),
    "category": rng.choice(["Electronics", "Books", "Home"], n),
    "payment_method": rng.choice(["card", "cash", "wallet"], n),
    "segment": rng.choice(["consumer", "business"], n),
    "quantity": rng.integers(1, 6, n),
    "amount": rng.uniform(50, 2500, n).round(2),
}).assign(
    ship_date=lambda d: d["order_date"] + pd.Timedelta(days=2),
    status=lambda d: np.where(d["amount"] > 2000, "priority", "standard"),
).to_csv("sales_data.csv", index=False)

df = pd.read_csv("sales_data.csv", parse_dates=["order_date"])

# Simple running total
df["cumulative_sales"] = df["amount"].cumsum()

# Running total within each region
df = df.sort_values("order_date")
df["cumulative_sales_by_region"] = df.groupby("region")["amount"].cumsum()

print(df[["order_date", "region", "amount", "cumulative_sales_by_region"]].head(10))

2. Multiple Cumulative Operations

df["cum_sales"] = df["amount"].cumsum()
df["cum_max"] = df["amount"].cummax()
df["cum_min"] = df["amount"].cummin()
df["running_avg"] = df["amount"].expanding().mean()   # expanding window average

3. Real-World Example: Monthly Running Totals

monthly = (
    df
    .groupby([df["order_date"].dt.to_period("M"), "region"])
    .agg(total_sales=("amount", "sum"))
    .reset_index()
)

# Calculate cumulative sales per region over months
monthly["cumulative_sales"] = monthly.groupby("region")["total_sales"].cumsum()

print(monthly)

4. Best Practices in 2026

  • Always sort your DataFrame by the time column before applying cumulative functions
  • Use groupby() + cumsum() for segmented running totals
  • Combine cumsum() with expanding() for running statistics
  • Use .cumsum() to create useful features like "days since first purchase" or "cumulative revenue"
  • Be careful with NaN values — they can break cumulative calculations (use .fillna(0) when appropriate)

How Cumulative Methods Work

A cumulative method walks down a column in its current order and keeps a running result. cumsum() adds each value to everything before it, cummax() and cummin() remember the highest and lowest value so far, and cumprod() multiplies, which is useful for compounding growth rates. All of them skip missing values by default and continue from the last valid result. The output always has the same length and index as the input, so you can store it as a new column next to the original.

Because the result depends on row order, sort the data by date (or by whatever defines "before") before you call any cumulative method.

Worked Example: Running Totals and Compounded Growth

Here we track year-to-date sales and turn monthly growth rates into an index value.

import pandas as pd

m = pd.DataFrame({
    "month": pd.period_range("2026-01", periods=4, freq="M"),
    "sales": [100, 120, 90, 150],
    "growth": [0.00, 0.10, -0.05, 0.20],
})

m["ytd_sales"] = m["sales"].cumsum()
m["best_so_far"] = m["sales"].cummax()
m["index"] = (1 + m["growth"]).cumprod() * 100
m["index"] = m["index"].round(1)
print(m[["month", "ytd_sales", "best_so_far", "index"]])

The year-to-date column ends at 460, the best month so far stays at 120 until April, and the growth index shows the combined effect of all monthly changes.

Common Mistakes

  • Unsorted data: running totals are only meaningful in time order
  • Missing values: cumsum() skips NaN but keeps it in the output; fill with 0 if a gap means "no sales"
  • Forgetting to reset per group: use groupby(...).cumsum() for totals that restart per customer or year
  • Adding growth rates: growth compounds, so use cumprod() on 1 + rate

Quick Summary

  • cumsum, cummax, cummin, cumprod keep running results
  • Sort first
  • Combine with groupby() to restart per group

Conclusion

Cumulative operations like cumsum(), cummax(), and cummin() are powerful tools for time-based data manipulation. In 2026, combining them with groupby() allows you to create insightful running totals, growth metrics, and historical comparisons with very little code. These functions turn raw transactional data into valuable business intelligence.

Next steps:

  • Add cumulative sales or cumulative customer count columns to one of your current datasets and analyze the trends

Related Tutorials

Share:
Last updated: March 2026
Built-in Functions in Python 2026 str() in Python 2026: String Conversion + Modern Formatting & Best Practices memoryview with JAX in Python 2026: Zero-Copy NumPy → JAX Array Interop + Efficient ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + GPU Pinning & ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + ML Examples memoryview with NumPy & PyTorch in Python 2026: Zero-Copy Views, Efficient Slicing & ML Interop Examples memoryview with NumPy in Python 2026: Zero-Copy Views, Efficient Slicing & Real ML Examples memoryview() in Python 2026: Zero-Copy Magic for Large Binary Data + Real Examples import() in Python 2026: How It Works, Security Risks & Modern Alternatives (importlib) zip() in Python 2026: How to Use It, strict=True Behavior & Real-World Examples vars() in Python 2026: Accessing Object Namespace + Modern Introspection Patterns type() in Python 2026: Dynamic Type Inspection & Object Creation + Modern Patterns tuple() in Python 2026: Immutable Sequences + Modern Patterns & Best Practices super() in Python 2026: Method Resolution & Modern Inheritance Patterns sum() in Python 2026: Summing Iterables + Modern Numeric Patterns & Best Practices staticmethod() in Python 2026: Static Methods, Utility Functions & Modern Best Practices sorted() in Python 2026: Sorting Iterables + Modern Patterns & Best Practices slice() in Python 2026: Creating Slice Objects + Modern Patterns & Best Practices setattr() in Python 2026: Dynamic Attribute Setting + Modern Patterns & Safety set() in Python 2026: Mutable Sets Creation + Modern Patterns & Best Practices