Python 使用NumPy reduceat计算基于组的平均值
我知道我们可以对每个组、每个列进行求和、乘法等Python 使用NumPy reduceat计算基于组的平均值,python,numpy,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, r
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.mean.reduceat
和np.average.reduceat
不起作用,因为
np.multiply.reduceat(dummies,idx)[tags]
使用
np.add.reduceat
根据间隔移位idx
获得数据数组假人的每列总和,然后除以用np.bincount
计算的间隔长度-
AttributeError: 'function' object has no attribute 'reduceat'
另一种计算区间长度的方法是直接使用idx
-
np.add.reduceat(dummies, idx, axis=0)/np.bincount(tags)[:,None]
同样,我们可以避免使用np.unique
来获得idx
,如下所示-
np.diff(np.r_[idx,dummies.shape[0]])
该软件包(免责声明:我是其作者)以单行语句的形式提供了此类功能:
idx = np.r_[0,np.flatnonzero(groupIDs[1:] > groupIDs[:-1])+1]
对于这种情况(已排序的键),它提供线性和矢量化性能;虽然比Divakar发布的专用解决方案有更多的额外开销,但是Divakar已经有了这个假设。但取决于您如何衡量可维护性、自文档性和通用性,这可能是首选的替代方案 只有ufunc
具有reduceat
mean
和average
不是这种类型的函数。出于好奇,您尝试使用纯numpy(相对于使用pandas groupby)来实现这一点有什么原因吗?除了我对pandas的熟悉程度不如numpy,甚至不知道它也可以在pandas中实现之外,没有其他具体原因。再次感谢!我们如何将np.add.reduceat(dummies,idx,axis=0)/np.bincount(tags)[:,None]
的输出放到与dummies相同的维度-i、 e.我们在np.multiply.reduceat(dummies,idx)
中将实现什么,在末尾添加[tags]
。@Tony我不清楚关于tags
的查询。我在这里使用了tags
和np.bincount
来获得每个区间的计数,从而计算平均值。不确定您计划如何将其用于np.multiply.reduceat
。你能详细说明或重新措辞吗?对不清楚表示歉意。当调用任何一个求和
,相乘
等时,如原始帖子中的示例所示,即不除以np.bincount
获得平均值,则返回的数组与原始数组的形状相同。因此,我当前的问题是如何重塑np.add.reduceat(dummies,idx,axis=0)/np.bincount(tags)[:,None]
的输出,使其具有与原始数组相同的维度。在本例中,第一行的前4个元素将是0.25,下面两个元素将是0.5等等。我正在用所需的输出编辑我的问题。@Tony IIUC只是用标记编制索引:out[tags]
,其中out
是np.add.reduceat(dummies,idx,axis=0)/np.bincount(tags)[,None]
。那有用吗?当然,先生。
import numpy_indexed as npi
unique_groups, means = npi.group_by(groupIDs).mean(dummies)