Pandas Cumsum条件复位

问题描述 投票:0回答:1

我正在使用一个现有的解决方案,试图产生一个累积和,在某个值(在这种情况下,>= 16)之后重置。目前我得到了以下输出,但也有cumsum仍然大于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

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

python pandas numpy cumsum
1个回答
1
投票
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
投票

这里的答案与公认的答案略有不同。在Pandas中,对一列的累积和进行Perfrom,但如果总和为负,则重置为0。 可以帮你解决这个问题。

由于这个解决方案使用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]

0
投票

我认为,一个好的解决方案是一个 "带记忆的函数",应用于你感兴趣的列的每个值。

定义以下函数来计算你的总和。

def myCumSum(val):
    myCumSum.sum += val
    if myCumSum.sum > 16:
        myCumSum.sum = val
    return myCumSum.sum

注意这个函数有一个属性金额),应该在第一次调用该函数之前设置。

myCumSum.sum = 0

然后将其应用到 尺寸 列,并将结果保存为 阴毛 栏目。

df['cumsum'] = df.Size.apply(myCumSum)
© www.soinside.com 2019 - 2024. All rights reserved.