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

Pandas条件分组:基于谓词的分区聚合实现方案问询

基于列值条件的窗口聚合(替代循环方案)

你需要的**按当前行days值做条件聚合(≤、≥、等于)**可以通过Pandas的分组+累计求和实现,完全替代循环,效率提升明显。以下是具体实现:

一、基础实现(全局范围的条件聚合)

先明确需求:对每一行,计算所有days≤当前行days的amount总和(同理处理≥的情况)。

步骤1:计算每个days对应的amount总和

先把相同days的amount合并,得到每个days的总金额:

import pandas as pd
df = pd.DataFrame(data={
    'id': ['0001', '0001', '0001', '0002', '0002', '0003', '0003', '0004'],
    'days': [2, 5, 6, 3, 5, 4, 6, 8],
    'amount': [100, 150, 150, 200, 100, 300, 250, 200]
})

# 按days分组,计算每个days对应的amount总和
day_total = df.groupby('days')['amount'].sum()

步骤2:计算≤当前days的累计总和

对day_total按days升序排序后做累计求和,得到每个days对应的「所有≤该days的amount总和」,再映射回原DataFrame:

# 升序累计求和 → days≤当前值的总和
cum_le = day_total.sort_index().cumsum()
df['run_sum_le'] = df['days'].map(cum_le)

步骤3:计算≥当前days的累计总和

同理,按days降序排序后做累计求和,再映射回原DataFrame:

# 降序累计求和后重新按days排序 → days≥当前值的总和
cum_ge = day_total.sort_index(ascending=False).cumsum().sort_index()
df['run_sum_ge'] = df['days'].map(cum_ge)

步骤4:等于当前days的求和(你已实现的方法)

直接用map映射分组后的结果即可:

df['run_sum_eq'] = df['days'].map(day_total)

最终结果:

id  days  amount  run_sum_le  run_sum_ge  run_sum_eq
0  0001     2     100         100        1450         100
1  0001     5     150         850         850         250
2  0001     6     150        1250         600         400
3  0002     3     200         300        1350         200
4  0002     5     100         850         850         250
5  0003     4     300         600        1150         300
6  0003     6     250        1250         600         400
7  0004     8     200        1450         200         200

二、按id分组的条件聚合(如果需要在每个id内计算)

如果需求是每个id范围内,days≤当前行days的amount总和,可以调整为按id分组后做累计:

# 按id+days分组求和
id_day_total = df.groupby(['id', 'days'])['amount'].sum().reset_index()

# 按id分组,对days升序排序后计算累计和
id_day_total['run_sum_le'] = id_day_total.groupby('id').apply(
    lambda x: x.sort_values('days')['amount'].cumsum()
).reset_index(drop=True)

# 合并回原DataFrame
df = df.merge(id_day_total[['id', 'days', 'run_sum_le']], on=['id', 'days'], how='left')

三、为什么不用窗口函数直接实现?

Pandas的窗口函数(如rolling、expanding)主要基于行的顺序而非列值的条件匹配,无法直接实现「依赖当前行列值的全局条件聚合」。而分组+累计求和的方式,本质是先按列值聚合相同条件的行,再通过累计得到全局范围的条件总和,是更高效的方案。

内容的提问来源于stack exchange,提问作者Domenico Spidy Tamburro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 20:45:04