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.reduceat
和np.average.reduceat
无法正常工作,因为
AttributeError: 'function' object has no attribute 'reduceat'
答案 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发布的专业解决方案有更多的额外开销,但已经有了这个假设。但是,根据您如何衡量可维护性,自我可记录性和一般性,这可能是一个首选的替代方案。