numpy 计算1d阵列所有可能切片的平均值

yacmzcpb  于 2023-03-08  发布在  其他
关注(0)|答案(1)|浏览(132)

我有一个(大的)1D测量数据数组。我想计算由起始索引和终止索引定义的每个可能切片的平均值。就像在数据的两端切割,并对每个可能的切割取平均值。结果应该存储在一个正方形2D数组中(实际上是一个三角形,因为起始索引必须小于终止索引)。
使用循环是有效的,但是需要很长时间。
有没有办法加快速度?
我有这个代码:

N = 5
data = np.arange(N)  # example
av = np.zeros((N, N))
for i in range(av.shape[0]):
    for j in range(av.shape[1]):
        av[j, i] = np.mean(data[i:j+1])

这是可行的,但需要很长时间。对于类似的计算(元素的差异而不是切片的平均值),我发现了这个非常快速的解决方案:

dist = np.subtract.outer(data, data)

但我不知道如何用切片的平均值来计算。

juzqafwq

juzqafwq1#

一个选项,先求和,然后除以项目数:

a = np.arange(len(data))

av = (np.tril(np.repeat(data[:,None], len(data), axis=1)).cumsum(axis=0)
     /np.tril((a[:,None]-a+1))
     )

输出:

array([[0. , nan, nan, nan, nan],
       [0.5, 1. , nan, nan, nan],
       [1. , 1.5, 2. , nan, nan],
       [1.5, 2. , 2.5, 3. , nan],
       [2. , 2.5, 3. , 3.5, 4. ]])

中间体:

# repeat data to square shape and keep lower triangle
np.tril(np.repeat(data[:,None], len(data), axis=1))
array([[0, 0, 0, 0, 0],
       [1, 1, 0, 0, 0],
       [2, 2, 2, 0, 0],
       [3, 3, 3, 3, 0],
       [4, 4, 4, 4, 4]])

# get the cumulated sum
[…].cumsum()
array([[ 0,  0,  0,  0,  0],
       [ 1,  1,  0,  0,  0],
       [ 3,  3,  2,  0,  0],
       [ 6,  6,  5,  3,  0],
       [10, 10,  9,  7,  4]])

# compute the divider
a = np.arange(len(data))
array([0, 1, 2, 3, 4])

np.tril((a[:,None]-a+1))
array([[1, 0, 0, 0, 0],
       [2, 1, 0, 0, 0],
       [3, 2, 1, 0, 0],
       [4, 3, 2, 1, 0],
       [5, 4, 3, 2, 1]])
性能

一个1000整数输入(data = np.arange(1000)

# nested for loop
6.28 s ± 142 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# vectorized numpy
12.3 ms ± 427 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

相关问题