我在使用pandas groupby和numpy的np.average计算加权平均值时遇到困难。问题似乎是数据中的缺失(即缺失;在数据中,而不是在 weigths 中)。我在下面做了一个概念性的例子。
我想要的行为是,当数据丢失时,该记录的权重也会被忽略。简单地删除行不是一种选择,因为其他数据列都填充了数据。我认为np.ma.average正是我所需要的,但这也给了我NaN的结果。
有什么建议吗?
df = pd.DataFrame({ 'groups': ['a','a','b','a','b','b'],
'data': [3, 3, 4, 2, 2.5, np.nan],
'Weights': [1, 2, 1, 3, 1, 3]})
def wavg(subdf):
series = pd.Series()
for column in df.columns:
series['np.mean'] = np.mean(subdf['data'])
series['np.average (no weights)'] = np.average(subdf['data'])
series['np.average (weighted)'] = np.average(subdf['data'], weights=subdf['Weights'])
series['np.ma.average (weighted)'] = np.ma.average(subdf['data'], weights=subdf['Weights'])
return series
df.groupby('groups').apply(wavg)
这给了我
np.mean np.average np.average np.ma.average
(no weights) (weighted) (weighted)
groups
a 2.666667 2.666667 2.5 2.5
b 3.250000 NaN NaN NaN
==================================== 对于好奇,这是我最终使用的:
def wavg(subdf):
series = pd.Series()
for column in columns:
df = subdf.dropna(subset=[column])
if len(df) == 0:
series[str(column)] = np.nan
else:
series[str(column)] = np.average( df[column], weights=df['Weights'])
return series
答案 0 :(得分:1)
由于np.average
本身无法处理nan
,因此您必须自己处理它们。最简单的方法是在对subdf
进行任何操作之前对其进行子集化。在subdf = subdf.dropna(subset=['data'])
的开头添加wavg
,以清除“数据”列中包含NaN的行:
def wavg(subdf):
series = pd.Series()
subdf = subdf.dropna(subset=['data'])
series['np.mean'] = np.mean(subdf['data'])
series['np.average (no weights)'] = np.average(subdf['data'])
series['np.average (weighted)'] = np.average(subdf['data'], weights=subdf['Weights'])
series['np.ma.average (weighted)'] = np.ma.average(subdf['data'], weights=subdf['Weights'])
return series
正如我在评论中建议的那样,我从wavg
删除了循环。您只想返回每组的一组平均值(即一个平均值,一个平均值,一个加权平均值,一个屏蔽平均值)。但是对于你的循环,你为每个组重新计算同样的事情四次(因为你的DataFrame中有四列)。