python - 如何根据输入获取一维 numpy 数组的所有可能切片

标签 python python-3.x numpy

我有一个 numpy 数组

a = np.arange(12)
>>> [0,1,2,3,4,5,6,7,8,9,10,11]

我正在尝试像这样计算所有可能的累积和

np.cumsum[2:] + np.cumsum[:-2]
np.cumsum[3:] + np.cumsum[:-3]
...
np.cumsum[11:] + np.cumsum[:-11]

如何在没有循环的情况下实现这一点 我尝试做

starts = np.arange(2,12)
np.cumsum[starts:] + np.cumsum[:-starts]
but I get this error
TypeError: only integer scalar arrays can be converted to a scalar index

如何在没有 for 循环的情况下做到这一点

我正在尝试做什么

我正在尝试计算序列长度内所有可能时间范围的移动平均值。例如,如果我的数组大小为 10,我可以移动平均 1 个周期(没有意义),移动平均 2 个周期、3 个周期...10 个周期。我该如何实现这个目标。我想计算从 2 到 n 的移动平均值,其中 n 是序列的大小

最佳答案

不确定我是否完全理解了这个问题,您可以将以下内容作为起点。

您需要具有统一大小的数组才能利用矢量化。您无法通过简单的切片来做到这一点,但零填充在这种情况下可以有所帮助:

In [3]: a = np.arange(12)

In [4]: a
Out[4]: array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

In [15]: starts = np.arange(2,12)

In [18]: left = np.stack([np.pad(a,(0,s),mode="constant")[s:] for s in starts])

In [19]: left
Out[19]: 
array([[ 2,  3,  4,  5,  6,  7,  8,  9, 10, 11,  0,  0],
       [ 3,  4,  5,  6,  7,  8,  9, 10, 11,  0,  0,  0],
       [ 4,  5,  6,  7,  8,  9, 10, 11,  0,  0,  0,  0],
       [ 5,  6,  7,  8,  9, 10, 11,  0,  0,  0,  0,  0],
       [ 6,  7,  8,  9, 10, 11,  0,  0,  0,  0,  0,  0],
       [ 7,  8,  9, 10, 11,  0,  0,  0,  0,  0,  0,  0],
       [ 8,  9, 10, 11,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 9, 10, 11,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [10, 11,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [11,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0]])

这里您还需要将所有内容向左移动以获得正确的对齐方式:

In [27]: right = np.stack([ np.roll(np.pad(a, (s,0), mode="constant")[:-s], -s) for s in starts ])

In [28]: right
Out[28]: 
array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0],
       [0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0],
       [0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0],
       [0, 1, 2, 3, 4, 5, 6, 0, 0, 0, 0, 0],
       [0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0],
       [0, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0],
       [0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

现在您可以将矢量化的np.cumsum用于密集部分

In [41]: np.cumsum(left, axis=1) + np.cumsum(right, axis=1)
Out[41]:
array([[  2,   6,  12,  20,  30,  42,  56,  72,  90, 110, 110, 110],
       [  3,   8,  15,  24,  35,  48,  63,  80,  99,  99,  99,  99],
       [  4,  10,  18,  28,  40,  54,  70,  88,  88,  88,  88,  88],
       [  5,  12,  21,  32,  45,  60,  77,  77,  77,  77,  77,  77],
       [  6,  14,  24,  36,  50,  66,  66,  66,  66,  66,  66,  66],
       [  7,  16,  27,  40,  55,  55,  55,  55,  55,  55,  55,  55],
       [  8,  18,  30,  44,  44,  44,  44,  44,  44,  44,  44,  44],
       [  9,  20,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33],
       [ 10,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22],
       [ 11,  11,  11,  11,  11,  11,  11,  11,  11,  11,  11,  11]])

现在您可能需要清理结果才能获得您想要的结果,但我仍然不确定,如果您可以发布预期的输出,那就太好了。像这样的事情应该做:

In [50]: [ row[:-s] for row,s in zip(csum,starts) ]
Out[50]: 
[array([  2,   6,  12,  20,  30,  42,  56,  72,  90, 110]),
 array([ 3,  8, 15, 24, 35, 48, 63, 80, 99]),
 array([ 4, 10, 18, 28, 40, 54, 70, 88]),
 array([ 5, 12, 21, 32, 45, 60, 77]),
 array([ 6, 14, 24, 36, 50, 66]),
 array([ 7, 16, 27, 40, 55]),
 array([ 8, 18, 30, 44]),
 array([ 9, 20, 33]),
 array([10, 22]),
 array([11])]

关于python - 如何根据输入获取一维 numpy 数组的所有可能切片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50036888/

相关文章:

python - 何时在 Pyramid 中使用route_url或route_path?

python - Pytest:测试文件中具有模块范围的固定装置可以工作,但在 conftest.py 中会引发错误

python - 如何查找特定值的列号以及该位置的 CSV 文件

python - Spacy NLP 库 : what is maximum reasonable document size

python - 除了继承之外,在 `super() ` 内部使用 python `__init__ ` 的目的是什么?

python-3.x - 如何将字节数据转换为 python pandas 数据帧?

python - 创建可旋转的 3D 地球

python - Numpy 无法正确排列数组

python - 处理 numpy 数组中选定范围的值

python - 如何告诉 Python 重新导入我的脚本?