熊猫暨有条件重置

时间:2020-05-04 10:25:58

标签: python pandas numpy cumsum

我正在使用一个现有的解决方案来尝试产生一个累积的总和,该总和在某个值(在这种情况下> = 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

有什么想法可以纠正这个问题吗?

3 个答案:

答案 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)