【问题标题】:Python transcription of Matlab's accumarray [duplicate]Matlab的accumarray的Python转录[重复]
【发布时间】:2019-09-15 06:10:30
【问题描述】:

我想得到与 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 的示例:对该函数的引用仅出现在标题中(作者仅给出了对该函数的非常严格的定义)。就我而言,有一个实际示例似乎比其他讨论中考虑的更普遍。

【问题讨论】:

  • 我编辑了我的问题以解释为什么据我所知它不是重复的。实际上,您提到的讨论的标题应该修改,因为Matlab的accumarray函数没有出现在问题的主体中,除了它给出了这个函数的定义,如果我们考虑描述,在一般情况下似乎是错误的在官方文档中给出。
  • 有道理。看起来没有直接的等价物,但here 看起来有人构建了基于 scipy 的东西。也许该解决方案适用于您的情况?
  • 它不起作用,因为第二个参数是标量。实际上,我不明白为什么它是一个标量,因为 accumarray 官方文档中给出的示例将向量作为第二个参数。我使用您所指的 accum 函数得到的错误是“ValueError:accmap 的初始尺寸必须与 a.shape 相同”,这似乎意味着 Matlab 能够将标量解释为向量,但我不明白它是如何工作的。

标签: python pandas matlab numpy scipy


【解决方案1】:

我没有详细测试它,但这个功能应该是你正在寻找的。它处理了一些 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)

【讨论】:

    猜你喜欢
    • 2015-04-12
    • 2013-11-12
    • 2015-07-25
    • 2013-06-19
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 2014-05-12
    • 1970-01-01
    相关资源
    最近更新 更多