如果我计算一个groupby对象的平均值,并且在一个组中有一个NaN,则NaN将被忽略。即使使用np.mean,它仍然仅返回所有有效数字的平均值。我希望一旦有一个NaN进入小组,就会返回NaN的行为。这是行为的简化示例
import pandas as pd
import numpy as np
c = pd.DataFrame({'a':[1,np.nan,2,3],'b':[1,2,1,2]})
c.groupby('b').mean()
a
b
1 1.5
2 3.0
c.groupby('b').agg(np.mean)
a
b
1 1.5
2 3.0
我想收到以下结果:
a
b
1 1.5
2 NaN
我知道我可以预先替换NaN,并且我可能可以编写自己的聚合函数以在NaN进入该组后立即返回NaN。不过,此功能不会进行优化。
您知道使用优化功能实现所需行为的参数吗?
顺便说一句,我认为期望的行为是在以前版本的熊猫中实现的。
答案 0 :(得分:4)
mean(skipna=False)
,但不起作用 GroupBy聚合方法(最小值,最大值,均值,中位数等)具有skipna
参数,该参数适用于此确切任务,但目前(2020年5月)似乎有一个{{ 3}}(发行日期为2020年3月),这使其无法正常工作。
基于以下注释的完整工作示例:bug,@Serge Ballesta
>>> import pandas as pd
>>> import numpy as np
>>> c = pd.DataFrame({'a':[1,np.nan,2,3],'b':[1,2,1,2]})
>>> c.fillna(np.inf).groupby('b').mean().replace(np.inf, np.nan)
a
b
1 1.5
2 NaN
有关其他信息和更新,请点击上面的链接。
答案 1 :(得分:3)
默认情况下,pandas
跳过Nan
值。您可以通过指定Nan
使其包含skipna=False
:
In [215]: c.groupby('b').agg({'a': lambda x: x.mean(skipna=False)})
Out[215]:
a
b
1 1.5
2 NaN
答案 2 :(得分:1)
使用skipna
选项-
c.groupby('b').apply(lambda g: g.mean(skipna=False))
答案 3 :(得分:1)
另一种方法是使用默认不忽略的 value ,例如np.inf
:
>>> c = pd.DataFrame({'a':[1,np.inf,2,3],'b':[1,2,1,2]})
>>> c.groupby('b').mean()
a
b
1 1.500000
2 inf
答案 4 :(得分:0)
有三种不同的方法:
c.groupby('b').apply(lambda g: g.mean(skipna=False))
c.groupby('b').agg({'a': lambda x: x.mean(skipna=False)})
method3 = c.groupby('b').sum()
nan_index = c[c['b'].isna()].index.to_list()
method3.loc[method3.index.isin(nan_index)] = np.nan
答案 5 :(得分:0)
我登陆这里是为了寻找一种快速(矢量化)的方法,但是没有找到。另外,在复数的情况下,groupby
的行为有点奇怪:它不像mean()
,并且使用sum()
它将转换所有值为NaN
的组进入0+0j
。
所以,这是我想出的:
设置:
df = pd.DataFrame({
'a': [1, 2, 1, 2],
'b': [1, np.nan, 2, 3],
'c': [1, np.nan, 2, np.nan],
'd': np.array([np.nan, np.nan, 2, np.nan]) * 1j,
})
gb = df.groupby('a')
默认行为:
gb.sum()
Out[]:
b c d
a
1 3.0 3.0 0.000000+2.000000j
2 3.0 0.0 0.000000+0.000000j
一个NaN
会杀死该小组:
cnt = gb.count()
siz = gb.size()
mask = siz.values[:, None] == cnt.values
gb.sum().where(mask)
Out[]:
b c d
a
1 3.0 3.0 NaN
2 NaN NaN NaN
如果组中的所有值均为NaN
,则仅NaN
:
cnt = gb.count()
gb.sum() * (cnt / cnt)
out
Out[]:
b c d
a
1 3.0 3.0 0.000000+2.000000j
2 3.0 NaN NaN
推论:复数的平均值:
cnt = gb.count()
gb.sum() / cnt
Out[]:
b c d
a
1 1.5 1.5 0.000000+2.000000j
2 3.0 NaN NaN