Question
I have a pandas DataFrame named df:
import pandas as pd
df = pd.DataFrame({
'c1': [10, 11, 12],
'c2': [100, 110, 120]
})
It looks like this:
c1 c2
0 10 100
1 11 110
2 12 120
How can I iterate over the rows of this DataFrame?
For each row, I want to access its cell values by column name, like this:
for row in df.rows:
print(row['c1'], row['c2'])
I found similar examples suggesting these approaches:
for date, row in df.T.iteritems():
pass
and
for row in df.iterrows():
pass
However, I do not understand what the row object actually is in these examples, or how to use it correctly.
Short Answer
By the end of this page, you will understand how row iteration works in a Pandas DataFrame, what iterrows() returns, how to access values by column name, and when to prefer alternatives like itertuples() or vectorized Pandas operations.
Concept
In Pandas, a DataFrame is a table-like data structure with rows and columns. Each column has a name, and each row has an index.
When you iterate over a DataFrame row by row, Pandas does not give you a plain dictionary automatically. Instead, the exact object depends on the method you use:
df.iterrows()returns pairs of(index, row)rowis a Pandas Series- You can access values from that Series using column names like
row['c1']
Example:
for index, row in df.iterrows():
print(index, row['c1'], row['c2'])
Why this matters:
- Beginners often expect
rowto be a dictionary - In reality,
rowbehaves more like a labeled one-dimensional array - Knowing this helps you read and write DataFrame code correctly
Also, row iteration is usually not the fastest Pandas approach. Pandas is designed for vectorized operations, which means working with entire columns or the whole DataFrame at once.
For example, instead of looping:
for index, row df.iterrows():
(row[] + row[])
Mental Model
Think of a DataFrame as a spreadsheet.
- The DataFrame is the whole sheet
- A row is one horizontal line in the sheet
- A Series is like taking one row and turning it into a labeled list
So when you use iterrows(), Pandas hands you:
- the row label (
index) - a row object (
Series) where:- the labels are the column names
- the values are the cell values in that row
It is similar to receiving this for the first row:
index = 0
row = pd.Series({'c1': 10, 'c2': 100})
Then you can do:
row['c1']
row['c2']
So the main idea is: a row from iterrows() is a Series with column names as keys.
Syntax and Examples
Basic row iteration with iterrows()
import pandas as pd
df = pd.DataFrame({
'c1': [10, 11, 12],
'c2': [100, 110, 120]
})
for index, row in df.iterrows():
print(index, row['c1'], row['c2'])
Output:
0 10 100
1 11 110
2 12 120
What is happening?
df.iterrows()produces one row at a time- Each item is a pair:
(index, row) indexis the row label (0,1,2)
Step by Step Execution
Consider this code:
import pandas as pd
df = pd.DataFrame({
'c1': [10, 11],
'c2': [100, 110]
})
for index, row in df.iterrows():
print('index:', index)
print('c1:', row['c1'])
print('c2:', row['c2'])
Step-by-step
-
Pandas creates a DataFrame with two columns:
c1andc2. -
df.iterrows()starts producing rows one at a time. -
On the first loop:
indexis0rowis a Series like:
c1 10 c2 100 Name: 0, dtype: int64
Real World Use Cases
Row iteration is useful when you need to process records one at a time, especially when each row triggers some external action.
Common practical examples
-
Sending API requests
- Each row contains user data or product data
- You loop through rows and send one request per record
-
Generating files or messages
- Each row becomes an email, report line, or JSON payload
-
Data validation
- Check each row for missing or invalid combinations of values
-
Database migration scripts
- Read rows from a CSV into a DataFrame, then insert or transform records one by one
-
Logging or auditing
- Compare fields in each row and record issues
Example: building payloads
for _, row in df.iterrows():
payload = {
'amount': row['c1'],
'total': row['c2']
}
print(payload)
But if your goal is calculation or transformation inside Pandas, prefer vectorized code when possible.
Real Codebase Usage
In real projects, developers usually avoid row iteration unless they truly need it.
Common patterns
1. Vectorized transformations first
df['difference'] = df['c2'] - df['c1']
This is preferred over looping.
2. Use iterrows() for readability when row labels matter
for index, row in df.iterrows():
if row['c1'] < 0:
print(f"Invalid row at index {index}")
3. Use itertuples() for performance
for row in df.itertuples(index=False):
print(row.c1, row.c2)
4. Guard clauses during row processing
for _, row in df.iterrows():
if pd.isna(row['c1']):
continue
(row[])
Common Mistakes
1. Forgetting that iterrows() returns (index, row)
Broken code:
for row in df.iterrows():
print(row['c1'])
Why it fails:
rowis actually a tuple, not a Series
Correct code:
for index, row in df.iterrows():
print(row['c1'])
2. Expecting row to be a dictionary
A row from iterrows() behaves similarly to a mapping because you can use column names, but it is a Series, not a plain dict.
for _, row in df.iterrows():
print(type(row))
3. Modifying row and expecting the DataFrame to change
Comparisons
Row iteration methods in Pandas
| Method | What it returns | Access style | Speed | Best use |
|---|---|---|---|---|
iterrows() | (index, Series) | row['c1'] | Slower | Beginner-friendly row access by column name |
itertuples() | named tuples | row.c1 | Faster | Performance-sensitive loops |
| Vectorized operations | whole columns/arrays | df['c1'] + df['c2'] | Fastest | Most calculations and transformations |
vs
Cheat Sheet
Quick reference
Iterate with iterrows()
for index, row in df.iterrows():
print(index, row['c1'], row['c2'])
- Returns
(index, row) rowis apandas.Series- Access values by column name:
row['column_name']
Ignore the index if you do not need it
for _, row in df.iterrows():
print(row['c1'])
Faster row iteration with itertuples()
for row in df.itertuples(index=False):
print(row.c1, row.c2)
Best for calculations: vectorized code
df['sum'] = df[] + df[]
FAQ
What does df.iterrows() return in Pandas?
It returns an iterator of (index, row) pairs. The row value is a Pandas Series.
How do I access a column value while iterating rows?
With iterrows(), use the column name:
for _, row in df.iterrows():
print(row['c1'])
Is iterrows() the best way to loop through a DataFrame?
Not usually. It is fine for simple row-by-row tasks, but vectorized operations or itertuples() are often better.
What is the difference between iterrows() and itertuples()?
iterrows() returns Series objects and allows row['c1']. itertuples() returns named tuples and is usually faster.
Can I modify the DataFrame by changing row inside ?
Mini Project
Description
Build a small script that reads a Pandas DataFrame of products and prints a summary for each row. This demonstrates how to iterate through rows, access values by column name, and decide when a loop is appropriate.
Goal
Create a script that loops through a DataFrame and prints a formatted message for each product using values from named columns.
Requirements
[ "Create a DataFrame with columns named product, price, and quantity", "Iterate through each row using a Pandas row iteration method", "Access each value by its column name or row attribute", "Print a sentence showing the product name and total value for that row" ]
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.
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.
Convert Bytes to String in Python 3
Learn how to convert bytes to str in Python 3 using decode(), text mode, and proper encodings with practical examples.