How to Use pandas fillna to Fill Only Specific DataFrame Columns In-Place

Select the target columns to create a view, then call fillna(inplace=True) on that subset to update the underlying BlockManager blocks without copying data.

The fillna method in the pandas-dev/pandas repository provides robust missing-value handling by operating on the internal BlockManager storage. Because the base NDFrame class defines fillna without a column subset parameter, filling only specific columns in-place requires selecting a view of those columns before invoking the method.

Why fillna Operates on the Entire DataFrame

The core implementation of fillna resides in pandas/core/missing.py and is inherited by both Series and DataFrame from the NDFrame mix-in in pandas/core/generic.py. When executed on a DataFrame, the method iterates over all blocks in the BlockManager (pandas/core/internals/managers.py) and applies fill logic column-by-column. There is no built-in subset parameter to restrict the operation to specific columns, so you must create a column view first.

Method 1: Fill Selected Columns Using In-Place Views

In pandas/core/frame.py, the DataFrame.__getitem__ method returns a view that references the same underlying data blocks as the original DataFrame. Because this view shares the memory layout, calling fillna with inplace=True updates the original data without copying.

import pandas as pd

df = pd.DataFrame({
    "A": [1, None, 3],
    "B": [None, 5, 6],
    "C": [7, 8, None]
})

# Select columns and fill in-place

cols_to_fill = ["A", "C"]
df[cols_to_fill].fillna(0, inplace=True)

After execution, columns A and C contain filled values while column B remains unchanged. This works because the view writes directly back to the blocks managed by the BlockManager.

Method 2: Iterate Over Individual Series

When you need to fill columns with different values or conditions, loop through the column names and call fillna on each Series individually. The Series implementation in pandas/core/series.py handles the in-place modification for that specific column block.

for col in ["A", "C"]:
    df[col].fillna(0, inplace=True)

This approach is useful when applying different fill values per column but incurs slightly more overhead due to the Python loop.

Method 3: Dictionary Mapping for Column-Specific Values

You can pass a dictionary to fillna where keys are column names and values are the fill scalars. According to the implementation in pandas/core/generic.py, this updates only the keys present in the dictionary while leaving other columns untouched.

df.fillna({"A": 0, "C": 0}, inplace=True)

Note that this method still processes the entire DataFrame structure, but only modifies the specified column keys within the BlockManager.

Memory and Performance Considerations

Using df[cols].fillna(value, inplace=True) is the most memory-efficient approach because it avoids creating a copy of the data. The view created by __getitem__ references the same blocks stored in pandas/core/internals/managers.py, allowing the operation to modify the original arrays directly. In contrast, assigning the result back with df[cols] = df[cols].fillna(value) creates an intermediate copy before assignment, doubling memory usage temporarily.

Summary

  • fillna is implemented in pandas/core/missing.py and inherited from NDFrame in pandas/core/generic.py.
  • There is no native subset parameter; you must select columns via __getitem__ to create a view.
  • Column views share the BlockManager layout, so inplace=True updates the original DataFrame without copying.
  • Dictionary-based filling in pandas/core/generic.py offers a concise syntax for multiple column-specific values.

Frequently Asked Questions

Does pandas fillna have a subset parameter for DataFrames?

No. The fillna method defined in pandas/core/generic.py does not accept a subset argument. To fill only specific columns, you must first select those columns using df[['col1', 'col2']] or df.loc[:, ['col1', 'col2']] to create a view, then call fillna on that selection.

What is the difference between inplace=True and reassignment?

When inplace=True, fillna returns None and modifies the underlying BlockManager blocks directly. When you use reassignment (df[cols] = df[cols].fillna(0)), pandas creates a new DataFrame fragment with filled values and then writes it back to the original DataFrame's columns, which uses more memory but avoids SettingWithCopy warnings.

Can I use this method on a MultiIndex DataFrame?

Yes. The column selection logic works identically on MultiIndex columns. Select the specific level or column names as you would with a flat index: df[('level1', 'colA')].fillna(0, inplace=True) or df[[('level1', 'colA'), ('level1', 'colB')]].fillna(0, inplace=True). The BlockManager handles the block placement correctly regardless of the index type.

Is there a performance difference between dictionary filling and view selection?

Dictionary filling requires the method to check every column against the dictionary keys internally, while view selection restricts the operation to specific blocks immediately. For large DataFrames with many columns, selecting a view first is typically faster because it reduces the iteration overhead in the BlockManager loop.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s https://instagit.com/install.md

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client