Python Pandas: How to Set Cell Value in Pandas DataFrame
Setting or updating individual cell values in a Pandas DataFrame is one of the most common operations in data manipulation. Whether you need to correct a typo, fill in missing data, or update specific records, Pandas provides several methods to accomplish this. This guide covers four practical approaches - using at, loc, replace, and iloc - with clear examples, outputs, and best practices.
Setting Up a Sample DataFrame
All examples in this guide use the following DataFrame as a starting point:
import pandas as pd
data = pd.DataFrame({
'name': ['Emily', 'Michael', 'James', 'Sophia', 'Daniel'],
'subjects': ['java', 'php', 'html/css', 'python', 'R'],
'marks': [98, 90, 78, 91, 87]
})
print(data)
Output:
name subjects marks
0 Emily java 98
1 Michael php 90
2 James html/css 78
3 Sophia python 91
4 Daniel R 87
Method 1: Using DataFrame.at[]
The at accessor is the fastest way to get or set a single cell value by row label and column name. It is also capable of adding new rows to the DataFrame if the specified index does not already exist.
import pandas as pd
data = pd.DataFrame({
'name': ['Emily', 'Michael', 'James', 'Sophia', 'Daniel'],
'subjects': ['java', 'php', 'html/css', 'python', 'R'],
'marks': [98, 90, 78, 91, 87]
})
# Update an existing cell
data.at[0, 'marks'] = 99
# Add a completely new row by specifying a non-existing index
data.at[5, 'name'] = 'Tom'
data.at[5, 'subjects'] = 'jsp'
data.at[5, 'marks'] = 100
print(data)
Output:
name subjects marks
0 Emily java 99.0
1 Michael php 90.0
2 James html/css 78.0
3 Sophia python 91.0
4 Daniel R 87.0
5 Tom jsp 100.0
Use at when you need to read or write a single scalar value. It is optimized for speed and is significantly faster than loc for single-cell access.
Method 2: Using DataFrame.loc[]
The loc accessor selects data by row label and column name, just like at. However, loc is more versatile because it also supports slicing, boolean indexing, and setting values for multiple cells at once.
import pandas as pd
data = pd.DataFrame({
'name': ['Emily', 'Michael', 'James', 'Sophia', 'Daniel'],
'subjects': ['java', 'php', 'html/css', 'python', 'R'],
'marks': [98, 90, 78, 91, 87]
})
# Update the last row using loc
data.loc[4, 'name'] = 'Tom'
data.loc[4, 'subjects'] = 'react-js'
data.loc[4, 'marks'] = 80
print(data)
Output:
name subjects marks
0 Emily java 98
1 Michael php 90
2 James html/css 78
3 Sophia python 91
4 Tom react-js 80
Setting Multiple Cells with a Condition
One of the major advantages of loc is the ability to update cells based on a condition:
import pandas as pd
data = pd.DataFrame({
'name': ['Emily', 'Michael', 'James', 'Sophia', 'Daniel'],
'subjects': ['java', 'php', 'html/css', 'python', 'R'],
'marks': [98, 90, 78, 91, 87]
})
# Set marks to 100 for all students who scored above 90
data.loc[data['marks'] > 90, 'marks'] = 100
print(data)
Output:
name subjects marks
0 Emily java 100
1 Michael php 90
2 James html/css 78
3 Sophia python 100
4 Daniel R 87
Method 3: Using DataFrame.replace()
The replace method is ideal when you want to update a cell based on its current value rather than its position. This is particularly useful for fixing typos or standardizing data across the entire DataFrame.
import pandas as pd
data = pd.DataFrame({
'name': ['Emily', 'Michael', 'James', 'Sophia', 'Daniel'],
'subjects': ['java', 'php', 'html/css', 'python', 'R'],
'marks': [98, 90, 78, 91, 87]
})
# Replace a specific value wherever it appears
data.replace('Michael', 'Tom', inplace=True)
print(data)
Output:
name subjects marks
0 Emily java 98
1 Tom php 90
2 James html/css 78
3 Sophia python 91
4 Daniel R 87
You can also replace multiple values at once using a dictionary:
import pandas as pd
data = pd.DataFrame({
'name': ['Emily', 'Michael', 'James', 'Sophia', 'Daniel'],
'subjects': ['java', 'php', 'html/css', 'python', 'R'],
'marks': [98, 90, 78, 91, 87]
})
data.replace({'java': 'Java', 'php': 'PHP', 'R': 'R Language'}, inplace=True)
print(data)
Output:
name subjects marks
0 Emily Java 98
1 Michael PHP 90
2 James html/css 78
3 Sophia python 91
4 Daniel R Language 87
When using replace, the method searches the entire DataFrame by default. If the value you are replacing exists in multiple columns, all occurrences will be updated. To limit replacement to a specific column, apply it directly on that column: data['name'].replace('ravi', 'ravi kumar', inplace=True).
Method 4: Using DataFrame.iloc[]
The iloc accessor works with integer-based positions (0, 1, 2, ...) rather than labels. This is useful when you know the exact row and column position of the cell you want to modify.
import pandas as pd
data = pd.DataFrame({
'name': ['Emily', 'Michael', 'James', 'Sophia', 'Daniel'],
'subjects': ['java', 'php', 'html/css', 'python', 'R'],
'marks': [98, 90, 78, 91, 87]
})
# Update a single cell at row 2, column 2 (marks)
data.iloc[2, 2] = 95
print(data)
Output:
name subjects marks
0 Emily java 98
1 Michael php 90
2 James html/css 95
3 Sophia python 91
4 Daniel R 87
Updating Multiple Rows at Once
You can pass a list of row indices and column indices to update multiple cells simultaneously:
import pandas as pd
data = pd.DataFrame({
'name': ['Emily', 'Michael', 'James', 'Sophia', 'Daniel'],
'subjects': ['java', 'php', 'html/css', 'python', 'R'],
'marks': [98, 90, 78, 91, 87]
})
# Set the 'name' column (index 0) to 'updated' for rows 0, 1, and 3
data.iloc[[0, 1, 3], [0]] = 'updated'
print(data)
Output:
name subjects marks
0 updated java 98
1 updated php 90
2 James html/css 78
3 updated python 91
4 Daniel R 87
Common Mistake: Using Chained Indexing
A frequent pitfall when setting cell values is chained indexing, which can silently fail to update the original DataFrame:
import pandas as pd
data = pd.DataFrame({
'name': ['Tom', 'Anna', 'David'],
'marks': [98, 90, 78]
})
# WRONG: chained indexing, may not modify the original DataFrame
data['marks'][0] = 50
print(data)
This may produce a SettingWithCopyWarning and the value might not be updated in the original DataFrame, depending on the Pandas version and internal memory layout.
The correct approach is to always use loc, iloc, or at:
# CORRECT: use loc to set the value
data.loc[0, 'marks'] = 50
print(data)
Output:
name marks
0 Tom 50
1 Anna 90
2 David 78
Avoid chained indexing like df['col'][row] for assignment. It can lead to unpredictable behavior. Always use df.loc[row, 'col'], df.iloc[row, col], or df.at[row, 'col'] instead.
Quick Comparison of Methods
| Method | Access Type | Best For | Supports Multiple Cells |
|---|---|---|---|
at[] | Label-based | Single cell (fastest) | No |
loc[] | Label-based | Single or multiple cells, conditional updates | Yes |
iloc[] | Position-based | Single or multiple cells by integer index | Yes |
replace() | Value-based | Replacing specific values across the DataFrame | Yes |
Each method has its strengths.
- Use
atfor maximum speed on single cells - Use
locfor label-based access with conditional logic - Use
ilocwhen working with integer positions - USe
replacewhen you need to swap values regardless of their location in the DataFrame.