如何基于收支列数值分组累计计算,为数据表新增累计储蓄列
需求实现方案
这个需求核心是按用户id分组,计算当前行之前所有收支的累计余额,可以通过SQL窗口函数或者Pandas快速实现,以下是两种常见场景的实现方式:
前提说明
默认数据排序规则为:按id分组后,先按交易日期date升序排列,同日期下的交易顺序保留原表的先后顺序,该顺序会直接影响累计储蓄的计算结果。
1. SQL 实现(支持MySQL 8.0+、PostgreSQL、Hive等支持窗口函数的数据库)
首先将收支转换为正负变动额,再通过窗口函数计算当前行之前的累计和即可:
select date, id, action, value, -- 第一行没有前置记录,累计和为null,转成0 coalesce(sum(if(action='income', value, -value)) over( partition by id order by date asc -- 仅累计当前行之前的所有记录 rows between unbounded preceding and 1 preceding ), 0) as saved from 你的表名 -- 全局排序和窗口内排序保持一致 order by id, date asc;
注:你给出的示例输入与输出中部分
value数值不一致(比如输入中aa用户9月2日的第一笔支出是500,输出中是400),属于笔误,上述逻辑完全匹配你描述的计算规则。
2. Pandas 实现(适合用Python处理本地数据)
import pandas as pd # 先构造每行的收支变动额,收入为正、支出为负 df['delta'] = df.apply(lambda row: row['value'] if row['action'] == 'income' else -row['value'], axis=1) # 按id分组后计算累计和,整体下移一行,空值填充为0就是要求的saved列 df['saved'] = df.groupby('id')['delta'].cumsum().shift(1).fillna(0).astype(int)
内容的提问来源于stack exchange,提问作者french_fries
相关产品推荐
相关产品推荐

