忽略 NaN 的 Pandas 聚合
Posted
技术标签:
【中文标题】忽略 NaN 的 Pandas 聚合【英文标题】:Pandas aggregation ignoring NaN's 【发布时间】:2014-11-26 13:01:31 【问题描述】:我汇总了我的 Pandas 数据框:data
。具体来说,我想通过 [origin
和 type
] 的元组获得平均值和总和 amount
s。对于求平均和求和,我尝试了以下 numpy 函数:
import numpy as np
import pandas as pd
result = data.groupby(groupbyvars).agg('amount': [ pd.Series.sum, pd.Series.mean]).reset_index()
我的问题是amount
列包含NaN
s,这导致上面代码的result
有很多NaN
的平均值和总和。
我知道pd.Series.sum
和pd.Series.mean
默认都有skipna=True
,那为什么我仍然在这里得到NaN
s?
这个我也试过了,明显不行:
data.groupby(groupbyvars).agg('amount': [ pd.Series.sum(skipna=True), pd.Series.mean(skipna=True)]).reset_index()
编辑:
根据@Korem 的建议,我还尝试使用partial
,如下所示:
s_na_mean = partial(pd.Series.mean, skipna = True)
data.groupby(groupbyvars).agg('amount': [ np.nansum, s_na_mean ]).reset_index()
但得到这个错误:
error: 'functools.partial' object has no attribute '__name__'
【问题讨论】:
你能发布一些示例数据吗?此外,首先,而不是pd.Series.sum
- 只需使用 'sum'
- 代码应该采用更快的路径。
谢谢,我决定使用pd.Series.sum
,因为它有一个skipna
选项。阅读@Korem 的回答,我现在使用np.nansum
。但是np.nanmean
在我的numpy 版本(1.7.1)中不可用。我将尝试发布代表性数据,这可能需要一段时间。
【参考方案1】:
使用numpy的nansum和nanmean:
from numpy import nansum
from numpy import nanmean
data.groupby(groupbyvars).agg('amount': [ nansum, nanmean]).reset_index()
作为旧版本 numpy 的解决方法,也是修复上次尝试的一种方法:
当您执行pd.Series.sum(skipna=True)
时,您实际上调用了该方法。如果你想像这样使用它,你想定义一个partial。所以如果你没有nanmean
,让我们定义s_na_mean
并使用它:
from functools import partial
s_na_mean = partial(pd.Series.mean, skipna = True)
【讨论】:
谢谢,我用的是numpy-1.7.1-py2.7-win32.egg,不喜欢nanmean
抛出错误:'module' object has no attribute 'nanmean'
。 (我刚刚查了一下,nanmean
是 1.8.0 版本中的新功能
但是 np.nansum
似乎也被添加到了 1.8.0 版本中。奇怪的是我没有得到同样的错误......
谢谢Korem,我试过了,但没用,我编辑了我的问题,给出了错误。另外,默认情况下skipna=True
不是pd.Series.mean
吗?
@Zhubarb 默认是开启的,这说明你看到的问题不是你想的那样。
pandas doc : "skipna : boolean, default True", "Exclude NA/null values. If a entire row/column is NA, result will be NA"【参考方案2】:
可能为时已晚,但无论如何它可能对其他人有用。
试试apply函数:
import numpy as np
import pandas as pd
def nan_agg(x):
res =
res['nansum'] = x.loc[ not x['amount'].isnull(), :]['amount'].sum()
res['nanmean'] = x.loc[ not x['amount'].isnull(), :]['amount'].mean()
return pd.Series(res, index=['nansum', 'nanmean'])
result = data.groupby(groupbyvars).apply(nan_agg).reset_index()
【讨论】:
以上是关于忽略 NaN 的 Pandas 聚合的主要内容,如果未能解决你的问题,请参考以下文章
如何在 pandas DataFrame 中忽略滚动平均值计算的 NaN 值?
pandas计算dataframe数据行的均值(mean)实战:设置skipna=False则计算行均值时不会忽略NaN值