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

如何按id列分组计算cost总和,忽略omit=True的组最后一行

问题描述

现有一个包含3列的DataFrame:

  • id:整数类型,相同id的行已连续排列
  • cost:浮点类型
  • omit:布尔类型,多数行值为False,部分id的最后一行值为True

需求是新增total_cost列,计算每个id对应的cost总和,但需要忽略该id组中最后一行且omit=True的记录。

已完成分组求和的代码:

df["total_cost"] = df.groupby("id")["cost"].transform("sum")

但不确定如何以向量化方式实现「若组最后一行omit=True则减去该行cost」的逻辑。

示例输入输出如下:

id cost omit   total_cost
0  1.1  False  2.1
0  1.0  False  2.1
0  2.2  True   2.1
1  3.2  False  3.2
1  4.0  True   3.2
2  0.5  False  1.2
2  0.4  False  1.2
2  0.3  False  1.2
解决方案

你的思路完全正确——先计算全量分组总和,再对符合条件的组扣除对应值,这种方式比过滤后再求和更高效,尤其是数据量大的时候。可以通过以下向量化步骤实现:

  1. 标记每个组的最后一行:
    用groupby('id').cumcount(ascending=False)可以得到每个组内从后往前的序号,序号为0的就是该组最后一行。

  2. 提取需要扣除的cost值:
    筛选出「是组最后一行且omit=True」的记录,提取对应的id和cost,做成一个以id为索引的Series。

  3. 对分组总和做扣除修正:
    用transform把上述扣除值映射到每个组,没有需要扣除的组则用0填充,最后从原总和中减去该值。

完整代码如下:

import pandas as pd

# 示例数据
df = pd.DataFrame({
    'id': [0,0,0,1,1,2,2,2],
    'cost': [1.1,1.0,2.2,3.2,4.0,0.5,0.4,0.3],
    'omit': [False, False, True, False, True, False, False, False]
})

# 1. 计算分组总和
df['total_cost'] = df.groupby('id')['cost'].transform('sum')

# 2. 标记组最后一行,并筛选出需要扣除的记录
is_last_row = df.groupby('id').cumcount(ascending=False) == 0
deduct_series = df.loc[is_last_row & df['omit'], ['id', 'cost']].set_index('id')['cost']

# 3. 对每个组应用扣除值,无扣除则减0
df['total_cost'] -= df['id'].map(deduct_series).fillna(0)

运行后得到的total_cost列完全符合示例要求。这种方式全程用Pandas的向量化操作,避免了循环,效率很高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 14:52:59