Skip to main content

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
tip

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
warning

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
danger

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

MethodAccess TypeBest ForSupports Multiple Cells
at[]Label-basedSingle cell (fastest)No
loc[]Label-basedSingle or multiple cells, conditional updatesYes
iloc[]Position-basedSingle or multiple cells by integer indexYes
replace()Value-basedReplacing specific values across the DataFrameYes

Each method has its strengths.

  • Use at for maximum speed on single cells
  • Use loc for label-based access with conditional logic
  • Use iloc when working with integer positions
  • USe replace when you need to swap values regardless of their location in the DataFrame.