提问人:FuS 提问时间:3/3/2023 更新时间:3/3/2023 访问量:36
计算一维数组所有可能切片的平均值
Calculation of average of all possible slices of 1d-array
问:
我有一个(大的)一维测量数据数组。我想计算由开始索引和停止索引定义的每个可能切片的平均值。就像在我的数据的两端进行切割,并平均每一个可能的切割。 结果应存储在正方形 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)
但是我没有弄清楚如何用切片的平均值来做到这一点。
答:
0赞
mozway
3/3/2023
#1
一个带有求和的选项,然后除以项目数:
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)
评论
1赞
FuS
3/3/2023
我印象深刻......谢谢你的教训。
评论