忽略 NaN 的 Pandas 聚合

Posted

技术标签:

【中文标题】忽略 NaN 的 Pandas 聚合【英文标题】:Pandas aggregation ignoring NaN's 【发布时间】:2014-11-26 13:01:31 【问题描述】:

我汇总了我的 Pandas 数据框:data。具体来说,我想通过 [origintype] 的元组获得平均值和总和 amounts。对于求平均和求和,我尝试了以下 numpy 函数:

import numpy as np
import pandas as pd
result = data.groupby(groupbyvars).agg('amount': [ pd.Series.sum, pd.Series.mean]).reset_index() 

我的问题是amount列包含NaNs,这导致上面代码的result有很多NaN的平均值和总和。

我知道pd.Series.sumpd.Series.mean 默认都有skipna=True,那为什么我仍然在这里得到NaNs?

这个我也试过了,明显不行:

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 结合两个字符串忽略 nan 值

如何在 pandas DataFrame 中忽略滚动平均值计算的 NaN 值?

pandas计算dataframe数据行的均值(mean)实战:设置skipna=False则计算行均值时不会忽略NaN值

在 Python Pandas 中使用聚合函数时如何忽略值 0?

如何在 Python 的滚动平均值计算中忽略 NaN

进行聚合时如何忽略数据框中的特定列