How to Drop Rows Pandas: Complete Guide to DataFrame.drop()

To remove a specific row in Pandas, use DataFrame.drop() with the row's index label and axis=0 (the default), which returns a new DataFrame excluding that label.

The pandas-dev/pandas repository implements row removal through the DataFrame.drop() method in pandas/core/frame.py, providing a label-based interface that differs from positional indexing. When you need to drop rows pandas style, understanding that this method operates on index labels—not integer positions—is critical for accurate data manipulation.

How DataFrame.drop() Works Under the Hood

The drop() method implementation lives in pandas/core/frame.py within the DataFrame class, where it validates supplied labels against the Index object before constructing the reduced frame. This architecture delegates index operations to pandas/core/indexes/base.py while inheriting shared functionality from NDFrame in pandas/core/generic.py. Because drop rows pandas operations rely on index labels rather than integer positions, you must supply the actual label value (or list of values) you want to exclude.

Dropping Rows by Index Label

When removing data, you must reference the index label exactly as it appears in the DataFrame.

Removing a Single Row

Pass the label string or value to drop():

import pandas as pd

df = pd.DataFrame({
    "A": [10, 20, 30, 40],
    "B": ["a", "b", "c", "d"]
}, index=["row1", "row2", "row3", "row4"])

# Remove the row labelled 'row3'

df_without_row3 = df.drop("row3")
print(df_without_row3)

Output:


       A  B
row1  10  a
row2  20  b
row4  40  d

Removing Multiple Rows

Supply a list of labels to eliminate several rows simultaneously:


# Drop multiple rows and mutate in place

df.drop(["row1", "row4"], inplace=True)
print(df)

Output:


       A  B
row2  20  b
row3  30  c

Converting Positional Indices to Labels

If you only know the integer position (e.g., the third row), retrieve its label via df.index before calling drop():

df = pd.DataFrame({
    "X": [1, 2, 3, 4],
    "Y": [5, 6, 7, 8]
})

# Get the label of the third row (position 2)

label_to_remove = df.index[2]
df = df.drop(label_to_remove)
print(df)

Output:


   X  Y
0  1  5
1  2  6
3  4  8

Handling Missing Labels with Error Control

By default, drop() raises a KeyError if a label does not exist. Use errors='ignore' to skip missing labels silently without raising exceptions:

df = pd.DataFrame({"val": [100, 200]}, index=["a", "b"])
df2 = df.drop("c", errors="ignore")  # No exception raised

print(df2)

Output:


   val
a  100
b  200

Modifying DataFrames In-Place vs. Returning Copies

The drop() method returns a new DataFrame by default, leaving the original object unchanged. To modify the existing DataFrame, set inplace=True:

  • Returning a copy (default): df_new = df.drop("row1")
  • In-place modification: df.drop("row1", inplace=True)

Note: Using inplace=True returns None and prevents method chaining.

Chaining Operations After Dropping Rows

Because drop() returns a DataFrame (when inplace=False), you can chain it with methods like reset_index() to clean up the resulting index:

df = pd.DataFrame({"score": [5, 7, 9]}, index=["p1", "p2", "p3"])
df = df.drop("p2").reset_index(drop=True)
print(df)

Output:


   score
0      5
1      9

Key Source Files and Implementation Details

The row-dropping functionality spans three critical files in the pandas-dev/pandas repository:

File Role
pandas/core/frame.py Contains the DataFrame.drop() method definition and label validation logic
pandas/core/generic.py Houses the NDFrame base class providing shared dropping functionality
pandas/core/indexes/base.py Implements the core index machinery that validates and processes labels

Summary

  • Index-based removal: drop() uses index labels, not integer positions—convert positions to labels using df.index[pos] when necessary
  • Error handling: Set errors='ignore' to skip non-existent labels instead of raising KeyError
  • Copy vs. in-place: Default behavior returns a new DataFrame; use inplace=True to modify the original object
  • Method chaining: Return values can be chained with reset_index() or other DataFrame methods for streamlined workflows
  • Source location: Core implementation resides in pandas/core/frame.py with index operations delegated to pandas/core/indexes/base.py

Frequently Asked Questions

What is the difference between drop() and positional deletion for removing rows?

The drop() method removes rows by index label, while positional approaches like iloc rely on integer location. To drop rows pandas style using a known position, first convert the position to a label with df.index[position], then pass that label to drop().

Why does drop() raise a KeyError when the row clearly exists?

This occurs when you pass an integer to drop() but the DataFrame uses string labels (or vice versa). The method strictly matches against the index type. Verify your index values using df.index to ensure you are passing the correct label type and not a positional integer.

Is inplace=True better for memory performance in large DataFrames?

While inplace=True modifies the object directly and can save memory in some scenarios, modern Pandas often creates copies internally regardless of this parameter. For reliable, chainable operations and to avoid side effects, prefer the default copy-returning behavior: df = df.drop(labels).

How do I drop the last row without knowing its specific label?

Use negative indexing to retrieve the last label: df.drop(df.index[-1]). This works because df.index[-1] returns the final label, which drop() then uses to remove the corresponding row.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s https://instagit.com/install.md

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client