Question
In Pandas, I can delete a column from a DataFrame successfully with:
del df['column_name']
But why does this not work?
del df.column_name
Since it is possible to access a column as a Series using df.column_name, I expected deleting it the same way to work as well.
Short Answer
By the end of this page, you will understand how Pandas column access works, why bracket-based access and dot-based access are not equivalent, and why del df['column_name'] is the correct way to remove a DataFrame column. You will also learn when dot notation is safe to use, when it is risky, and what patterns real Python codebases prefer.
Concept
In Pandas, a DataFrame column can often be read in two different ways:
df['column_name']
and sometimes:
df.column_name
These look similar, but they are not the same concept.
df['column_name']is item access.df.column_nameis attribute access.
That difference matters.
Why del df['column_name'] works
When you write:
del df['column_name']
Python calls DataFrame behavior for deleting an item by key. In other words, Pandas knows you are asking to remove a column from the table.
This is the intended and supported way to delete a column with del.
Why del df.column_name does not work
When you write:
del df.column_name
Python treats this as deleting an , not deleting a DataFrame column. A DataFrame is a Python object with many real attributes and methods such as:
Mental Model
Think of a DataFrame like a cabinet.
- Bracket access (
df['salary']) means: “Open the drawer labeledsalary.” - Dot access (
df.salary) means: “Ask the cabinet object whether it has a property calledsalary.”
Sometimes the cabinet is helpful and says, “Yes, I can give you the salary drawer that way too.” But that does not mean salary is a real built-in property of the cabinet.
So reading through dot notation may work as a convenience, but deleting through dot notation is like trying to unscrew part of the cabinet itself rather than removing a drawer by label.
That is why bracket syntax is the safer and more precise tool for DataFrame columns.
Syntax and Examples
Reading a column
import pandas as pd
df = pd.DataFrame({
'name': ['Ana', 'Ben'],
'age': [25, 30]
})
print(df['age'])
print(df.age)
Both may print the same Series:
0 25
1 30
Name: age, dtype: int64
However, df.age only works when the column name is a valid attribute name and does not conflict with existing DataFrame attributes.
Deleting a column correctly
import pandas as pd
df = pd.DataFrame({
'name': ['Ana', 'Ben'],
'age': [25, 30]
})
del df['age']
print(df)
Output:
name
0 Ana
Ben
Step by Step Execution
Consider this example:
import pandas as pd
df = pd.DataFrame({
'city': ['Paris', 'Rome'],
'population': [2.1, 2.8]
})
del df['population']
print(df)
Step by step
1. Create the DataFrame
df = pd.DataFrame({
'city': ['Paris', 'Rome'],
'population': [2.1, 2.8]
})
The DataFrame has two columns:
citypopulation
2. Delete one column by key
del df['population']
Python sees del used with [...], so it performs item deletion. Pandas interprets 'population' as a column label and removes that column from the DataFrame.
Real World Use Cases
Deleting DataFrame columns is common in data work.
1. Cleaning imported CSV data
You may load a file that contains unnecessary columns:
df = df.drop(columns=['unnamed: 0'])
Typical examples:
- extra index columns
- debug fields
- export-only metadata
2. Removing sensitive information
Before sharing data, developers often remove columns such as:
- phone number
- address
- internal user IDs
del df['email']
3. Preparing features for machine learning
Some columns should not be used for training:
- target labels
- free-text notes
- high-cardinality IDs
X = df.drop(columns=['target'])
4. API response shaping
If a backend service reads tabular data before returning JSON, it may remove internal columns first.
df = df.drop(columns=['internal_flag', 'created_by'])
5. Reporting and dashboards
Analysts often trim raw datasets to keep only columns needed for charts or summaries.
Real Codebase Usage
In real Python projects, developers usually prefer explicit column access with brackets.
Common pattern: explicit over convenient
Instead of:
df.total
many codebases prefer:
df['total']
Why:
- clearer intent
- safer with unusual column names
- avoids collisions with DataFrame methods
- easier for teammates to understand
Common pattern: dropping multiple columns
df = df.drop(columns=['temp_col', 'debug_col'])
This is common in data pipelines because it scales well when removing several columns.
Common pattern: guard before deleting
if 'age' in df.columns:
del df['age']
This avoids errors if the schema changes.
Common pattern: validation in ETL scripts
required_columns = ['id', 'name', 'email']
missing = [col for col required_columns col df.columns]
missing:
ValueError()
Common Mistakes
1. Assuming dot access and bracket access are identical
Broken expectation:
del df.age
Why it is wrong:
- dot syntax is attribute-oriented
- bracket syntax is column-oriented
Use this instead:
del df['age']
2. Using dot notation with invalid column names
Broken code:
print(df.first name)
This is invalid Python syntax.
Use:
print(df['first name'])
3. Using dot notation with names that clash with DataFrame methods
df = pd.DataFrame({'count': [1, 2, 3]})
print(df.count) # this is a DataFrame method, not your column values
Use:
print(df[])
Comparisons
| Operation | Syntax | Works for all column names? | Deletes in place? | Best use |
|---|---|---|---|---|
| Read column by label | df['col'] | Yes | Not applicable | Standard, reliable column access |
| Read column by attribute | df.col | No | Not applicable | Quick interactive exploration only |
Delete with del | del df['col'] | Yes | Yes | Simple in-place deletion of one column |
Delete with drop() | df.drop(columns=['col']) |
Cheat Sheet
# Read a column safely
df['col']
# Read a column with shortcut syntax (not always safe)
df.col
# Delete one column in place
del df['col']
# Delete one or more columns
df = df.drop(columns=['col1', 'col2'])
# Delete and ignore missing columns
df = df.drop(columns=['col1'], errors='ignore')
# Check before deleting
if 'col' in df.columns:
del df['col']
Rules to remember
df['col']is the standard way to access a column.df.colis only a convenience shortcut.- Not every column name works with dot notation.
del df['col']deletes a column.del df.colis attribute deletion, not proper column deletion.drop()is often better when deleting multiple columns or building data pipelines.
Edge cases
- Columns with spaces: use brackets
- Columns named like methods (
count,plot, ): use brackets
FAQ
Why does df.column_name work for reading but not for deleting?
Because reading with dot notation is a convenience feature for attribute lookup. It is not the same as true column item access, which is what deletion uses.
Is df.column_name ever recommended in Pandas?
It is sometimes fine for quick exploration in a notebook, but bracket syntax is safer and more consistent in real code.
What is the best way to remove a Pandas column?
Use either:
del df['col']
or:
df = df.drop(columns=['col'])
Should I use del or drop() in Pandas?
Use del for simple in-place removal of one column. Use drop() when removing multiple columns, chaining operations, or handling missing columns gracefully.
Why is dot notation risky in Pandas?
It can fail if the column name has spaces, is not a valid Python identifier, or conflicts with a DataFrame method or attribute.
Can I delete multiple columns with del?
Not in a single clean operation. For multiple columns, is usually better.
Mini Project
Description
Build a small data-cleaning script that removes unnecessary columns from a customer dataset. This demonstrates the difference between reading columns and deleting them, and gives practice using safe, production-style column operations in Pandas.
Goal
Create a script that loads a DataFrame, removes unwanted columns safely, and prints the cleaned result.
Requirements
- Create a DataFrame with at least four columns, including one sensitive column such as
email - Print one column using bracket syntax
- Remove one column using
del - Remove another column using
drop(columns=[...]) - Print the final cleaned DataFrame
Keep learning
Related questions
@staticmethod vs @classmethod in Python Explained
Learn the difference between @staticmethod and @classmethod in Python with clear examples, use cases, mistakes, and a mini project.
Call a Function by Name in a Python Module
Learn how to call a function by name in a Python module using strings, getattr, and safe patterns for dynamic function dispatch.
Catch Multiple Exceptions in One except Block in Python
Learn how to catch multiple exceptions in one Python except block using tuples, with examples, mistakes, and real-world usage.