Не уверен, что я полностью понял вопрос, вот что вы можете использовать в качестве отправной точки.
Вам нужны массивы одинакового размера, чтобы использовать векторизацию.Вы не можете сделать это с помощью простой нарезки, но заполнение нулями может помочь в этом случае:
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])]