Skip to main content

Python Pandas: How to Drop All Rows from a DataFrame (Emptying Data)

There are situations in data manipulation with Pandas where you might need to remove all rows from a DataFrame, effectively emptying it of its data while potentially keeping its column structure intact. This could be for resetting a DataFrame for new data, clearing intermediate results, or initializing an empty structure.

This guide explains several common and effective methods to drop all rows from a Pandas DataFrame.

The Goal: Emptying a DataFrame of Rows

Our objective is to take an existing Pandas DataFrame and remove all of its rows, leaving behind an empty DataFrame that (usually) retains the original column names and their data types, but has no data records.

Example DataFrame

import pandas as pd

data = {
'ProductID': ['A101', 'B202', 'C303', 'D404'],
'ProductName': ['Laptop', 'Mouse', 'Keyboard', 'Monitor'],
'Category': ['Electronics', 'Accessory', 'Accessory', 'Electronics'],
'Price': [1200, 25, 75, 300]
}

df_original = pd.DataFrame(data)
print("Original DataFrame:")
print(df_original)

Output:

Original DataFrame:
ProductID ProductName Category Price
0 A101 Laptop Electronics 1200
1 B202 Mouse Accessory 25
2 C303 Keyboard Accessory 75
3 D404 Monitor Electronics 300

The DataFrame.drop() method is primarily used to remove specified labels from rows or columns. By passing the DataFrame's entire index to it, you instruct Pandas to drop all rows.

Explanation

import pandas as pd

df = pd.DataFrame({
'ProductID': ['A101', 'B202', 'C303', 'D404'],
'ProductName': ['Laptop', 'Mouse', 'Keyboard', 'Monitor'],
'Category': ['Electronics', 'Accessory', 'Accessory', 'Electronics'],
'Price': [1200, 25, 75, 300]
})

# df.index contains all row labels (e.g., RangeIndex(start=0, stop=4, step=1))
print(f"DataFrame index: {df.index.tolist()}\n")

# ✅ Drop all rows by passing the DataFrame's index
df_emptied_drop = df.drop(df.index) # By default, drop operates on rows (axis=0)

print("DataFrame after df.drop(df.index):")
print(df_emptied_drop)

Output:

DataFrame index: [0, 1, 2, 3]

DataFrame after df.drop(df.index):
Empty DataFrame
Columns: [ProductID, ProductName, Category, Price]
Index: []
  • df.index: Returns an Index object containing all the row labels of the DataFrame.
  • df.drop(labels, axis=0): When axis=0 (the default), labels refers to row labels to be dropped. Passing df.index means "drop all rows identified by these labels."
  • By default, drop() returns a new DataFrame with the rows removed. The original df is unchanged unless inplace=True is used or the result is reassigned.

Using inplace=True

To modify the DataFrame directly without creating a new one:

import pandas as pd

df_inplace_example = pd.DataFrame({
'ProductID': ['A101', 'B202', 'C303', 'D404'],
'ProductName': ['Laptop', 'Mouse', 'Keyboard', 'Monitor'],
'Category': ['Electronics', 'Accessory', 'Accessory', 'Electronics'],
'Price': [1200, 25, 75, 300]
})

print("DataFrame before inplace drop:")
print(df_inplace_example)
print()

# ✅ Drop all rows in-place
df_inplace_example.drop(df_inplace_example.index, inplace=True)

print("DataFrame after df.drop(df.index, inplace=True):")
print(df_inplace_example)

Output:

DataFrame before inplace drop:
ProductID ProductName Category Price
0 A101 Laptop Electronics 1200
1 B202 Mouse Accessory 25
2 C303 Keyboard Accessory 75
3 D404 Monitor Electronics 300

DataFrame after df.drop(df.index, inplace=True):
Empty DataFrame
Columns: [ProductID, ProductName, Category, Price]
Index: []

Now df_inplace_example itself is empty.

Method 2: Using Slicing (df.iloc[0:0] or df[0:0])

You can select an empty slice of rows. This effectively creates a new DataFrame with the same columns but no rows.

import pandas as pd

df = pd.DataFrame({
'ProductID': ['A101', 'B202', 'C303', 'D404'],
'ProductName': ['Laptop', 'Mouse', 'Keyboard', 'Monitor'],
'Category': ['Electronics', 'Accessory', 'Accessory', 'Electronics'],
'Price': [1200, 25, 75, 300]
})

# ✅ Select an empty slice using .iloc
df_emptied_iloc = df.iloc[0:0]
# Or, more concisely using direct slicing (which often implies .iloc for integer slices)
# df_emptied_slice = df[0:0]

print("DataFrame after df.iloc[0:0]:")
print(df_emptied_iloc)

Output:

DataFrame after df.iloc[0:0]:
Empty DataFrame
Columns: [ProductID, ProductName, Category, Price]
Index: []
note
  • df.iloc[0:0] (or df[0:0]) selects rows starting at position 0 up to (but not including) position 0, resulting in an empty selection of rows while preserving the column structure.
  • This method creates a new empty DataFrame; assign it back if you want to modify the original variable (e.g., df = df.iloc[0:0]).

Method 3: Re-instantiating with Same Columns (pd.DataFrame(columns=df.columns))

You can create a brand new, empty DataFrame that has the same column names and dtypes as the original.

import pandas as pd

df = pd.DataFrame({
'ProductID': ['A101', 'B202', 'C303', 'D404'],
'ProductName': ['Laptop', 'Mouse', 'Keyboard', 'Monitor'],
'Category': ['Electronics', 'Accessory', 'Accessory', 'Electronics'],
'Price': [1200, 25, 75, 300]
})

print(f"Original columns: {df.columns}\n")

# ✅ Create a new empty DataFrame with the same columns
df_emptied_recreate = pd.DataFrame(columns=df.columns)

print("DataFrame after pd.DataFrame(columns=df.columns):")
print(df_emptied_recreate)
print()

print("Dtypes of new empty DataFrame:")
print(df_emptied_recreate.dtypes) # Dtypes are preserved (as object initially if no data)

Output:

Original columns: Index(['ProductID', 'ProductName', 'Category', 'Price'], dtype='object')

DataFrame after pd.DataFrame(columns=df.columns):
Empty DataFrame
Columns: [ProductID, ProductName, Category, Price]
Index: []

Dtypes of new empty DataFrame:
ProductID object
ProductName object
Category object
Price object
dtype: object
note
  • df.columns: Returns an Index object containing the column names of the original DataFrame.
  • pd.DataFrame(columns=...): Creates a new DataFrame with the specified column names and an empty index (no rows). The dtypes will be object if no data is provided to infer them, but the structure matches.

If you also want to completely remove the columns and have a truly empty DataFrame (no rows, no columns):

df_completely_empty = pd.DataFrame() # Or pd.DataFrame(None)
print("Completely empty DataFrame:")
print(df_completely_empty)

Consideration: Dropping Rows vs. Creating an Empty DataFrame

  • df.drop(df.index) and slicing (df.iloc[0:0]): These methods operate on an existing DataFrame to remove its rows. drop can modify in-place. Slicing always creates a new view/copy which then needs to be reassigned. They generally preserve column dtypes accurately because they start from an existing populated structure.
  • pd.DataFrame(columns=df.columns): This creates a new empty DataFrame. If you reassign df = pd.DataFrame(columns=df.columns), the original DataFrame object is replaced. The dtypes of the columns in the new empty DataFrame will be object until data is added, unless dtypes are explicitly provided during creation (which is more complex).

For simply clearing rows while keeping the column structure and their original dtypes as best as possible, df.drop(df.index, inplace=True) or df = df.iloc[0:0] are often preferred.

Conclusion

To drop all rows from a Pandas DataFrame, effectively emptying its data content:

  1. df.drop(df.index, inplace=True): This is a common and explicit way to remove all rows by targeting their index labels. Use inplace=True to modify the DataFrame directly.
  2. df = df.iloc[0:0] (or df = df[0:0]): Slicing to select an empty range of rows is a concise way to get an empty DataFrame with the same columns. This creates a new DataFrame.
  3. df = pd.DataFrame(columns=df.columns): Re-instantiating a new DataFrame with the original column names creates an empty structure. This also creates a new DataFrame.

Choose the method that best suits your workflow, considering whether you need to modify the DataFrame in-place or create a new empty one. df.drop(df.index) is often favored for its explicit intent.