pandas.isna() vs pandas.DataFrame.isna()
They call the same underlying method, so there is no functional difference.

Calling the dataframe member function is preferred for OOP patterns, but there are many redundancies/aliases in pandas and python in general.



In case you are curious, here is how the source code breaks down (it is a mess).

The DataFrame (pandas/core/frame.py) method is simply:

def isna(self):
    return super().isna()


Where DataFrame extends NDFrame (implemented in pandas/core/generic.py). NDFrame subsequently invokes:

def isna(self):
    return isna(self).__finalize__(self)


Which was imported here:

from pandas.core.dtypes.missing import isna, notna


In pandas/core/dtypes/missing.py:

def isna(obj):
    return _isna(obj)


The _isna function is later aliased as _isna = _isna_new because there is a deprecated method _isna_old(obj).

The _isna_new(obj) function then performs the logic operations:

def _isna_new(obj)
    if is_scalar(obj):
        return libmissing.checknull(obj)
    # hack (for now) because MI registers as ndarray
    elif isinstance(obj, ABCMultiIndex):
        raise NotImplementedError("isna is not defined for MultiIndex")
    elif isinstance(obj, type):
        return False
    elif isinstance(
        obj,
        (
            ABCSeries,
            np.ndarray,
            ABCIndexClass,
            ABCExtensionArray,
            ABCDatetimeArray,
            ABCTimedeltaArray,
        ),
    ):
        return _isna_ndarraylike(obj)
    elif isinstance(obj, ABCGeneric):
        return obj._constructor(obj._data.isna(func=isna))
    elif isinstance(obj, list):
        return _isna_ndarraylike(np.asarray(obj, dtype=object))
    elif hasattr(obj, "__array__"):
        return _isna_ndarraylike(np.asarray(obj))
    else:
        return obj is None


Ultimately, the DataFrame method passes itself as a parameter to the same function that you call with pandas.isna().