【问题标题】:Concatenating values in a 3d array to 2d array efficiently有效地将 3d 数组中的值连接到 2d 数组
【发布时间】:2021-06-04 09:12:07
【问题描述】:

我有一个 3 维数组 A,我想对其中一个轴上的值求和并创建一个包含总和的二维数组。

这可以通过使用循环遍历 3d 数组来简单地完成,但这样做非常慢。

A = np.sum(A,axis=0) 可以比幼稚的方式快得多,但是有更快的方法吗?

我在 Matlab 中发现了这个答案:https://www.mathworks.com/matlabcentral/answers/3643-efficiently-converting-a-3d-matrix-to-a-2d-matrix

我想知道在 Python 中是否有类似的有效方法。

以下是我正在寻找的:

A = np.ones((3, 3, 3))

# numpy magic ...

print (A)

/**********
* [3, 3, 3],
* [3, 3, 3],
* [3, 3, 3]
***********/

【问题讨论】:

  • 你附加的matlab线程只是连接,你说你想沿轴求和,在numpy中我很确定np.sum将是最快的解决方案。如果要复制matlab代码,可以使用np.transposenp.reshape

标签: python arrays numpy numpy-ndarray


【解决方案1】:

您可以使用np.sum() 沿指定轴对值求和,这可以作为降维函数

a = np.ones((3, 3, 3))
np.sum(a, axis=2) # sums along "channels" axis
np.sum(a, axis=1) # sums along "columns" axis
np.sum(a, axis=0) # sums along "rows" axis

【讨论】:

  • 这对回答问题没有任何帮助。
  • 现在看起来可能是这样,但在我发布答案后,在关于 np.sum 的部分中进行了编辑
【解决方案2】:

我认为最好的办法是使用方法ndarray.sum 而不是np.sum。内部处理将是相同的,但是当您使用该方法时,您不需要检查传入的对象是否已经是一个数组并可能转换它。话虽如此,开销的差异非常小。

内部循环已经用 C 语言编写并尽可能优化。我能想到的唯一额外改进是沿连续轴求和总是最快的。您可以使用 np.moveaxis 后跟 copy 之类的东西来确保这一点,以保证连续性:

def fastsum(x, axis):
    if x.strides[axis] != x.itemsize:
        x = np.moveaxis(x, axis, -1).copy(order="C")
        axis = -1
    return x.sum(axis)

这个功能不是很有效。对于小型数组,任何收益都可能被 python 和 numpy 对象协议的开销所淹没。最好的办法是确保以正确的顺序生成数组,然后在 C 连续数组上使用 x.sum(-1) 或在 Fortran 连续数组上使用 x.sum(0)

【讨论】:

    猜你喜欢
    • 2019-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-02
    • 2020-04-06
    • 1970-01-01
    相关资源
    最近更新 更多