在Pandas类型上,nanfunctions和regular函数表现相同

Chr*_*ris 5 python statistics numpy pandas

通常numpy.var()numpy.nanvar()缺少值时不同,对于numpy.std()numpy.nanstd().然而:

df = pd.DataFrame({'A': [1,2,3,4,5,6,7,8,9,10,np.NaN,np.NaN,np.NaN]})

print("np.var() " + " : "+ str(np.var(df["A"])))
print("np.nanvar() " + " : "+ str(np.nanvar(df["A"])))
print("np.std() " + " : "+ str(np.std(df["A"])))
print("np.nanstd() " + " : "+ str(np.nanstd(df["A"])))
Run Code Online (Sandbox Code Playgroud)

结果:

np.var() : 8.25
np.nanvar() : 8.25
np.std() : 2.8722813232690143
np.nanstd() : 2.8722813232690143
Run Code Online (Sandbox Code Playgroud)

为什么两者都一样?在np.var()或的文档中没有任何关于缺失值的内容np.std().

mir*_*ulo 7

这是因为numpy.std(resp.numpy.var)尝试委托给第一个参数的std(resp.var)方法,如果它不是ndarray(来自这里的源代码):

def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue):
    kwargs = {}
    if keepdims is not np._NoValue:
        kwargs['keepdims'] = keepdims

    if type(a) is not mu.ndarray:
        try:
            std = a.std
        except AttributeError:
            pass
        else:
            return std(axis=axis, dtype=dtype, out=out, ddof=ddof, **kwargs)

    return _methods._std(a, axis=axis, dtype=dtype, out=out, ddof=ddof,
                         **kwargs)
Run Code Online (Sandbox Code Playgroud)

所以,你只是在呼唤pandas.Series.std(0自由度).在Pandas库中,所有描述性统计函数都处理缺失值(从文档中可以看到带有缺失数据的计算).

这里要说的是,如果您拥有Pandas系列,那么首先使用Pandas数据类型方法而不是NumPy自由函数会更加清晰.


评论

这种行为是NumPy为许多函数所做的事情,它们使用类似数组的对象作为第一个参数 - 尝试在对象上使用相同的方法(如果存在),如果不使用某些回退.但情况并非总是如此 - 例如

>>> a = np.random.randint(0, 100, 5)

>>> a
array([49, 68, 93, 51, 94])

>>> np.sort(a) # not in-place
array([49, 51, 68, 93, 94])

>>> a
array([49, 68, 93, 51, 94])

>>> a.sort() # in-place

>>> a
array([49, 51, 68, 93, 94])
Run Code Online (Sandbox Code Playgroud)

此外,在大多数情况下,NaN处理在nanfunctions.py第一次调用中起作用_replace_nan,它将您的类型转换为ndarray,并将ndarray中的NaN值替换为不会影响它们执行的任何计算的值(即将np.nansumNaN替换为0,np.nanprod替换NaNs与1).然后他们打电话给他们的非NaN同行进行实际计算.(例如:np.nansum)

def nansum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue):
    a, mask = _replace_nan(a, 0)
    return np.sum(a, axis=axis, dtype=dtype, out=out, keepdims=keepdims)
Run Code Online (Sandbox Code Playgroud)

因此np.nansum,例如,调用Pandas系列,你实际上并没有最终使用,pandas.Series.sum因为系列首先被转换为ndarray _replace_nan.所以不要(我不确定你为什么会这样)假设或依赖sum你的系列被调用的方法.

# a silly example

>>> s = pd.Series([1, 2, 3, np.nan])

>>> s.sum = lambda *args, **kwargs: "instance sum"

>>> s.sum()
'instance sum'

>>> np.sum(s)
'instance sum'

>>> np.nansum(s)
6
Run Code Online (Sandbox Code Playgroud)