Если у вас много строк и не слишком много столбцов, вы можете подойти к нему следующим образом:
import numpy as np
def carry(sample,cap):
result = sample.copy()
for c in range(1,result.shape[1]):
result[:,c] += np.maximum(result[:,c-1]-cap,0)
result[:,:-1] = np.minimum(result[:,:-1],cap)
return result
вывод:
sample = np.array([[7, 4, 2,0], [3, 2, 1, 0]])
cap = 5
carry(sample,cap)
# [[5, 5, 3, 0],
[3, 2, 1, 0]]
[РЕДАКТИРОВАТЬ] решение без l oop
Несмотря на то, что это не может использовать полную векторизацию (и работает медленнее), она делает трюк без каких-либо циклов:
def carry(sample,cap):
fCarry = np.frompyfunc(lambda a,b:b+max(0,a-cap),2,1)
result = fCarry.accumulate(sample,dtype=np.object,axis=1)
return np.minimum(cap,result.astype(sample.dtype))
Накопление с пользовательским ufun c переносит лишнюю сумму (через шапку) к следующему элементу. Затем все элементы переносятся в указанное ограничение, если они закончились (их перенос уже передан следующему соседу)