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().
这是因为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)