In pandas, pct_change() compares each value with an earlier value and returns a fractional change; multiply the result by 100 to express it in percent units. cumsum() adds values progressively to produce a running total. Both methods follow the order of the rows, so sort your data first when sequence matters.
How pct_change() and cumsum() differ
| Method | Question it answers | Typical output | Key decision |
|---|---|---|---|
pct_change() |
How large is the change relative to an earlier observation? | A fraction such as 0.10 for a 10% increase |
Which earlier period to compare, and how to handle missing values |
cumsum() |
What is the accumulated total so far? | A running sum | Which values to include, the direction or axis, row order, and group boundary |
These answer different questions: relative change measures movement against a baseline, while a cumulative sum adds the values themselves. A cumulative total is not the same as a final aggregate sum, and a percent change is not a percentage-point difference.
As an Amazon Associate I earn from qualifying purchases.
Calculate fractional change with pct_change()
Despite its name, pct_change() returns a fractional relative change, not a value already expressed in percentage units. By default, it compares each row with the immediately preceding row. The first value has no earlier observation to compare with, so its result is missing. See the pandas DataFrame.pct_change API.
Free tools Windows power users keep installed
One-click scans. No signup required.
For example, the pandas API shows the Series [90, 91, 85] producing changes of about 0.011111 and -0.065934. Multiplying by 100 expresses these as approximately 1.1111% and -6.5934%.
#1 Best Overall
Choose the comparison interval
The periods parameter sets how many rows apart the comparison is. Its default is 1; setting periods=2 compares each value with the value two rows earlier. The API also supports freq for time-series index offsets. Choose an interval that matches the question you intend to answer rather than assuming every change should be compared with the previous row.
Convert the fraction to percent units
Multiply the fractional result by 100 when you want values such as 10 to represent 10 percent:
Rank #2
df["change_fraction"] = df["value"].pct_change()
df["change_percent"] = df["change_fraction"] * 100
Keep the fractional result if that representation is more useful for later calculations. Naming the two columns distinctly helps prevent a fraction such as 0.10 from being mistaken for a percent-unit value such as 10.
Handle missing observations deliberately
Current pandas documentation requires fill_method=None for pct_change() and marks the parameter for removal in a future version. The pandas 2.1.0 release notes deprecated fill_method and limit and recommend filling values explicitly before calculating changes. Older examples using pct_change(fill_method='ffill') or relying on default filling are version-specific legacy usage.
If carrying the last observed value forward is appropriate for your data, do that as a separate step:
df["change_fraction"] = df["value"].ffill().pct_change()
Forward filling changes the comparison baseline: a missing row takes the previous value, so the change at that row is zero, and the next row is compared with the carried-forward value. Use it only when that treatment reflects what a missing observation means in your data. Backward filling with .bfill() is another explicit option when it suits the analysis.
Calculate a running total with cumsum()
cumsum() accumulates values along the selected direction. For a Series, it returns a cumulative sum; the DataFrame method calculates cumulative sums over an axis. Applied to a column, each position represents the sum through that position in the supplied row sequence.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →df["running_total"] = df["value"].cumsum()
Because the operation follows row order, sort by the relevant date or sequence field first if the running total should be chronological. Otherwise, pandas will accumulate the values in the order they are supplied. The same order dependence applies to the adjacent-row comparison made by the default pct_change().
Best Value
Keep each entity’s history separate
When rows represent several products, accounts, or sensors, calculating directly on the full column can compare one entity with another or carry a total across entity boundaries. Grouped operations keep each entity’s calculation within its own history. Sort by entity and the intended sequence before grouping when the order should be chronological.
df = df.sort_values(["entity", "date"])
groups = df.groupby("entity")["value"]
df["change_fraction"] = groups.pct_change()
df["running_total"] = groups.cumsum()
The pandas groupby guide lists both pct_change() and cumsum() as group operations. Built-in group operations can also be broadcast to the original rows with transform when that form fits the surrounding code.
Quick Recap
References
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

