【问题标题】:Pandas Cumsum conditional resetPandas Cumsum 条件重置
【发布时间】:2020-05-04 10:25:58
【问题描述】:

我正在使用现有的解决方案来尝试生成在某个值(在本例中 >= 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】:
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

【讨论】:

  • 非常感谢!
【解决方案2】:

此处接受的答案略有不同: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]

【讨论】:

    【解决方案3】:

    我认为,一个好的解决方案是将“带记忆功能”应用于每个值 来自您感兴趣的列。

    定义以下函数来计算总和:

    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)
    

    【讨论】:

      猜你喜欢
      • 2019-04-04
      • 2018-05-24
      • 2016-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-28
      相关资源
      最近更新 更多