Search code examples
pythonpandasdataframefillna

Pandas fillna only on rows with at least 1 non-NaN value


Suppose I have a DataFrame constructed like this:

import pandas as pd
import numpy as np

df = pd.DataFrame(data = {"col1":[3, np.nan, np.nan, 21],
                          "col2":[4, np.nan, 12, np.nan],
                          "col3":[33, np.nan, 55, np.nan]})

Which looks like this:

    col1     col2     col3
0   3.0      4.0      33.0
1   NaN      NaN      NaN
2   NaN      12.0     55.0
3   21.0     NaN      NaN

I want to filter to the columns which have at least 1 non-NaN value, and then fillna in place.

If I do the following:

df.loc[df.dropna(thresh=1).index, :].fillna("fill value")

This creates a new DataFrame which has the values correctly filled, and has dropped the row which is all NaN.

But I want to preserve the all NaN row so I try to apply this in place:

df.loc[df.dropna(thresh=1).index, :].fillna("fill value", inplace=True)

but no changes are made to the original DataFrame - what am I doing wrong?


Solution

  • To clarify, you want all NaN rows to remain nans, but fill the other NaNs with a value? And inplace?

    Something like this should work:

    df.where(df.isnull().all(axis=1), df.fillna(100), inplace=True)
    

    The where keeps the values where the whole row is null, otherwise, replaces it with the df.fillna() value.