How to delete the last row of data of a pandas dataframe
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Removing the last row from a pandas DataFrame is simple, but there are still a few decisions hidden inside the task. You might want to drop the last row by position, drop the row whose index label happens to be last, or remove a trailing summary row while keeping real data intact. Using the right approach makes the code easier to read and safer when the DataFrame is empty or carries a meaningful index.
In day-to-day code, the most common answer is df.iloc[:-1]. That works well because pandas uses standard Python slice behavior, so the intent is obvious and the original DataFrame stays unchanged until you assign the result.
Remove the Last Row by Position
If you mean “keep everything except the final positional row,” iloc is usually the cleanest option. The iloc indexer is purely position-based, so [:-1] means start at the beginning and stop before the final row.
That produces a new DataFrame with the first three rows. The original orders variable is unchanged.
If you want the existing variable to refer to the shortened result, reassign it:
The .copy() call is useful when you plan to modify the result later. It makes the intent explicit and avoids confusion about whether later writes should affect a view or an independent object.
One nice detail is that slice indexing is forgiving. If the DataFrame is empty, df.iloc[:-1] still returns an empty DataFrame instead of raising an exception. That makes it a good default in ETL code where empty inputs are possible.
Drop the Final Index Label
Sometimes the index itself matters more than row position. In that case, it can be clearer to delete the last index label with drop.
This is still removing the last row, but it describes the operation in label terms rather than slice terms. That reads well in code that already treats the index as part of the data model.
The main downside is that inventory.index[-1] fails if the frame is empty. A safe helper is easy to write:
Use this style when the last index label has meaning, or when the rest of the codebase already uses drop operations heavily.
Decide Whether to Reset the Index
After deleting the last row, ask whether the current index should stay as-is. pandas will preserve the remaining index values unless you reset them.
Reset the index when downstream code expects a simple 0..n-1 sequence. Keep the original index when it carries identity, timestamps, or keys used later in joins and debugging. There is no universal rule here; the correct choice depends on what the index represents.
This also matters in method chains. If the next step merges on index or serializes the frame, resetting too early can silently change semantics.
Remove a Trailing Footer Only When It Is Really a Footer
A lot of data-cleaning code says “remove the last row,” but what it actually means is “remove the trailing total row.” Those are different rules. If the last row is a footer, express that business rule instead of always chopping off the end.
That version is safer because it documents why the row is being removed. If the data source later stops appending a summary line, you do not accidentally delete a valid record.
Common Pitfalls
One common mistake is writing df.iloc[:-1] and assuming pandas modified the original DataFrame in place. It did not. You have to assign the result if you want the variable to change.
Another problem is using df.index[-1] on an empty frame. That raises an error, while df.iloc[:-1] on an empty frame is fine.
A third issue is resetting the index automatically even though the old index carried meaning. That can break joins, audit trails, or tests that compare index values directly.
Finally, avoid deleting the last row purely because a sample file once had a footer there. If the operation is really about a total row, encode that rule directly.
Summary
- Use
df.iloc[:-1]when you want the simplest positional solution. - Use
df.drop(df.index[-1])when index labels are the main thing you are working with. - Reassign the result because neither approach changes the original DataFrame automatically.
- Reset the index only when downstream code needs a fresh positional index.
- If the last row is a footer or total, remove it by business rule rather than by position alone.

