我想得到与Python中Matlab的accumarray函数相同的结果。我知道还有其他一些讨论可以为这个问题提供解决方案,但我认为这种情况似乎更加困难。
它对应于this Matlab script的情况,其中包含以下行:
binned_data = accumarray(bins(all(bins>0,2),:),1/nrows,M(ones(1,ncols)));
我试图通过阅读the official documentation of accumarray来理解这种计算的含义,但是对我来说还不清楚。
您了解这一行的含义,并且知道如何通过某些Python库(numpy,scipy,pandas等)获得相同的结果吗?
编辑:据我了解,我的问题与this one不同。如您所见,在我的案例中,accumarray有3个输入参数,而其他讨论中的示例中只有2个输入参数。此外,在其他讨论中未提供使用accumarray的示例:对该函数的引用仅出现在标题中(作者仅给出了对该函数的非常严格的定义)。就我而言,有一个实际的例子似乎比其他讨论中考虑的例子更笼统。
答案 0 :(得分:0)
我并未对所有细节进行测试,但是此功能应该是您所需要的。它可以处理Matlab函数要做的几件事。
def accumarray(subs, vals, size=None, fun=np.sum):
if len(subs.shape) == 1:
if size is None:
size = [subs.values.max() + 1, 0]
acc = val.groupby(subs).agg(fun)
else:
if size is None:
size = [subs.values.max()+1, subs.shape[1]]
subs = subs.copy().reset_index()
by = subs.columns.tolist()[1:]
acc = subs.groupby(by=by)['index'].agg(list).apply(lambda x: val[x].agg(fun))
acc = acc.to_frame().reset_index().pivot_table(index=0, columns=1, aggfunc='first')
acc.columns = range(acc.shape[1])
acc = acc.reindex(range(size[1]), axis=1).fillna(0)
id_x = range(size[0])
acc = acc.reindex(id_x).fillna(0)
return acc
您可以进行简单的计算,例如:
val = pd.Series(np.arange(101, 106+1))
subs = pd.Series([1, 3, 4, 3, 4]) - 1
accumarray(subs, val)
或更复杂的东西,例如:
val = pd.Series(np.arange(101, 106+1))
subs = (pd.DataFrame([[1, 1], [2, 2], [3, 2], [1, 1], [2, 2], [4, 1]]) - 1)
accumarray(subs,val, [4, 4])
val = pd.Series(range(1, 10+1))
subs = pd.DataFrame([[1, 1], [1, 1], [1, 1], [1, 1], [2, 1], [2, 1], [2, 1], [2, 1], [2, 1], [2, 2]]) - 1
accumarray(subs, val, None, list)