我正在使用一个现有的解决方案来尝试产生一个累积的总和,该总和在某个值(在这种情况下> = 16)之后重置。目前,我得到以下输出,但是在某些情况下,总和仍大于16。
Size cumsum
8 8
8 16 ---correct
8 8
8 16 ---correct
7 7
6 13 (should be reset here since next value causes cumsum >16)
7 20 ---incorrect
6 6
5 11
2 13
我使用的代码是:
df = pd.DataFrame({'Size':[8,8,8,8,7,6,7,6,5,2]})
ls = []
cumsum = 0
last_reset = 0
for _, row in df.iterrows():
cumsum = cumsum + row.Size
ls.append(cumsum)
if cumsum >= 16:
last_reset = cumsum
cumsum = 0
df['cumsum'] = ls
有什么想法可以纠正这个问题吗?
答案 0 :(得分:2)
df = pd.DataFrame({'Size':[8,8,8,8,7,6,7,6,5,2]})
ls = []
cumsum = 0
last_reset = 0
for _, row in df.iterrows():
if cumsum + row.Size <= 16:
cumsum += row.Size
else:
last_reset = cumsum
cumsum = row.Size
ls.append(cumsum)
df['cumsum'] = ls
结果:
Size cumsum
0 8 8
1 8 16
2 8 8
3 8 16
4 7 7
5 6 13
6 7 7
7 6 13
8 5 5
9 2 7
答案 1 :(得分:1)
此处可接受的答案略有不同:Perfrom cumulative sum over a column but reset to 0 if sum become negative in Pandas可以帮助您解决这个问题。
由于此解决方案使用了numba,因此它将比普通的iterrows
解决方案快很多
@njit
def cumli(x, lim):
total = 0
result = []
for i, y in enumerate(x):
total += y
if (total) > lim:
total = y
result.append(total)
return result
cumli(df.Size.values, 16)
# [8, 16, 8, 16, 7, 13, 7, 13, 5, 7]
答案 2 :(得分:0)
我认为,一个好的解决方案是将“具有记忆的功能”应用于每个值 从您感兴趣的列中。
定义以下函数来计算总和:
def myCumSum(val):
myCumSum.sum += val
if myCumSum.sum > 16:
myCumSum.sum = val
return myCumSum.sum
请注意,此函数具有属性( sum ),应设置此属性 在第一次调用此函数之前。
myCumSum.sum = 0
然后将其应用于 Size 列,并将结果另存为 cumsum 列:
df['cumsum'] = df.Size.apply(myCumSum)