使用NumPy reduceat计算基于组的平均值

时间:2017-05-19 20:16:58

标签: python numpy

import numpy as np
import pandas as pd
dummies = np.array(pd.get_dummies(list('abdccadab'))) #categorical IV
groupIDs = np.array([10,10,10,10,20,20,30,30,30]) #groups(/strata)
_,idx,tags = np.unique(groupIDs, return_index=1, return_inverse=1)

我知道我们可以按照每列的总和,乘法等,例如

np.multiply.reduceat(dummies,idx)[tags]

但有没有办法计算这些垃圾箱的方法?

np.mean.reduceatnp.average.reduceat无法正常工作,因为

AttributeError: 'function' object has no attribute 'reduceat'

2 个答案:

答案 0 :(得分:2)

使用np.add.reduceat根据间隔转换dummies获取数据数组idx的每列总结,然后除以用np.bincount计算的间隔长度 -

np.add.reduceat(dummies, idx, axis=0)/np.bincount(tags)[:,None]

计算间隔长度的另一种方法是直接使用idx -

np.diff(np.r_[idx,dummies.shape[0]])

同样,我们可以避免使用np.unique获取idx,就像这样 -

idx = np.r_[0,np.flatnonzero(groupIDs[1:] > groupIDs[:-1])+1]

答案 1 :(得分:1)

numpy_indexed包(免责声明:我是其作者)提供此类功能作为单行声明:

import numpy_indexed as npi
unique_groups, means = npi.group_by(groupIDs).mean(dummies)

对于这种情况(已经排序的键),它提供线性和矢量化的性能;虽然比Divakar发布的专业解决方案有更多的额外开销,但已经有了这个假设。但是,根据您如何衡量可维护性,自我可记录性和一般性,这可能是一个首选的替代方案。