【问题标题】:averaging over subsets of array in numpy在numpy中对数组的子集进行平均
【发布时间】:2017-06-11 23:35:13
【问题描述】:

我有一个形状为 (10, 10, 10, 60) 的 numpy 数组。尺寸可以是任意的,但这只是一个示例。

我想通过对某些子集取平均值来将其减少为 (10, 10, 10, 20) 的数组,我有两种情况:

1:取每个(10, 10, 10, 20) 块的平均值,即有三个(10, 10, 10, 20) 块并取三者之间的平均值。这可以通过:m = np.mean((x[..., :20], x[..., 20:40], x[...,40:60]), axis=3) 来完成。我的问题是,当最后一个维度是任意的而不编写一些显式循环时,如何生成它?所以,我可以这样做:

x = np.random.rand(10, 10, 10, 60)
result = np.zeros((10, 10, 10, 20))
offset = 20
loops = x.shape[3] // offset
for i in range(loops):
    index = i * offset
    result += x[..., index:index+offset]
result = result / loops

但是,这似乎不太像 Python,我想知道是否有更优雅的方法来做到这一点。

2:另一种情况是,我想将其分解为 10 个形状为 (10, 10, 10, 2, 3) 的数组,然后沿这十个数组之间的第 5 维取平均值,然后将其重新整形为 @ 987654327@ 阵列按原计划。我可以重新整形数组,然后再次像以前一样取平均值并再次整形,但第二部分似乎很不优雅。

【问题讨论】:

  • 对于第 2 部分:您能否详细说明分解部分?或者给我们一个有效的循环实现?
  • 实际上,您的解决方案似乎适用于这两个部分!我只需要以不同的方式重塑,我想。让我试试!

标签: python numpy


【解决方案1】:

您可以重塑将最后一个轴一分为二,使第一个轴的长度与所需的块数相同,然后沿倒数第二个轴获得平均值 -

m,n,r = x.shape[:3]
out = x.reshape(m,n,r,3,-1).mean(axis=-2) # 3 is no. of blocks

或者,我们可以引入 np.einsum 以显着提升性能 -

In [200]: x = np.random.rand(10, 10, 10, 60)

In [201]: %timeit x.reshape(m,n,r,3,-1).mean(axis=-2)
1000 loops, best of 3: 430 µs per loop

In [202]: %timeit np.einsum('ijklm->ijkm',x.reshape(m,n,r,3,-1))/3.0
1000 loops, best of 3: 214 µs per loop

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 2013-04-04
    • 1970-01-01
    • 2015-09-04
    • 2023-02-08
    • 2017-03-01
    • 2017-08-20
    相关资源
    最近更新 更多