You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Pandas实现多用户存提记录的动态时序累计余额计算

解决多用户存提时序统计的冗余与动态列生成问题

看起来你在从单用户扩展到多用户统计时踩了两个坑:一是分组时间维度不统一导致的行数爆炸,二是没有找到动态生成用户列的正确姿势。我来帮你梳理下解决方案:

问题根源分析

你之前分别按Created(存款时间)和Finished(取款时间)分组统计,这两个时间轴的交集/并集会产生大量不必要的组合,直接导致行数从2500暴涨到39万+。而且这种分开统计的方式,很难对齐所有用户的时间维度,后续unstack自然会出问题。

正确的处理流程

我们需要先统一交易的时间维度,再按用户+时间分组,最后动态生成各用户的净变动和累计余额列。

1. 数据预处理:统一交易类型标记

首先把存款和取款记录转换成统一的类型标识(存款记为+1,取款记为-1),避免分开统计:

# 假设df2中,Deposits非空代表存款,Withdrawals非空代表取款
df2['transaction_type'] = df2.apply(
    lambda row: 1 if pd.notna(row['Deposits']) else -1,
    axis=1
)

2. 按时间+用户分组统计净变动

用同一个时间字段(比如交易发生时间Created)和用户分组,计算每个时间点每个用户的净存提次数:

# 按时间、用户分组,求和得到净变动(存款次数-取款次数)
net_mov_per_user = df2.groupby(['Created', 'name'])['transaction_type'].sum().rename('net_mov')

这一步得到的是一个MultiIndex Series,索引为(Created, name),值为对应时间点该用户的净变动,不会产生冗余行。

3. 计算各用户的累计余额

按用户分组对net_mov做累计求和,得到每个用户的余额变化:

# 按用户维度分组,累计求和得到余额
balance_per_user = net_mov_per_user.groupby('name').cumsum().rename('balance')

4. 动态生成用户列(宽表格式)

用unstack把用户从索引转成列,自动适配所有未知用户:

# 合并净变动和余额,转成宽表格式
final_result = pd.concat([net_mov_per_user, balance_per_user], axis=1).unstack('name')

最终结果会生成多级列:('net_mov', '用户名')和('balance', '用户名'),完美适配n个未知用户的需求。

完整示例代码

import pandas as pd

# 模拟多用户数据集
data = {
    'Created': ['2024-01-01', '2024-01-01', '2024-01-02', '2024-01-02', '2024-01-03'],
    'name': ['Peter', 'Peter', 'Alice', 'Peter', 'Alice'],
    'Deposits': [100, None, 200, 150, None],
    'Withdrawals': [None, 50, None, None, 80]
}
df2 = pd.DataFrame(data)
df2['Created'] = pd.to_datetime(df2['Created'])

# 1. 标记交易类型
df2['transaction_type'] = df2.apply(
    lambda row: 1 if pd.notna(row['Deposits']) else -1,
    axis=1
)

# 2. 按时间+用户统计净变动
net_mov_per_user = df2.groupby(['Created', 'name'])['transaction_type'].sum().rename('net_mov')

# 3. 计算累计余额
balance_per_user = net_mov_per_user.groupby('name').cumsum().rename('balance')

# 4. 动态生成用户列
final_result = pd.concat([net_mov_per_user, balance_per_user], axis=1).unstack('name')

print(final_result)

额外优化:填充缺失时间点

如果需要让时序图更连贯,可以用重采样填充缺失值:

# 按天重采样,缺失的净变动填0,余额用前值填充
final_result = final_result.resample('D').asfreq()
final_result['net_mov'] = final_result['net_mov'].fillna(0)
final_result['balance'] = final_result['balance'].ffill()

这样处理后,你就能直接用这个结果绘制多用户的存提对比时序图了。

内容的提问来源于stack exchange,提问作者klabbaparn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 17:52:32