如何在Ibis聚合语句的across中访问其他列实现条件求和?
在Ibis中通过across基于布尔列对其他列求和的可行方案
问题背景
通过mutate结合自定义函数生成了多个匹配is_pre|is_post规则的布尔列,希望在聚合操作中利用across简化逻辑,基于这些布尔列的True值对net_spend_amt列进行条件求和,替代重复编写的条件聚合代码。
解决方案
核心是在across的func参数中使用lambda函数接收选中的布尔列,再基于该列作为筛选条件对目标列求和。以下是完整实现代码:
(df .pipe(mutate_is_weeks_pre('pre_end_date', 'trn_dt', weeks=[2, 4, 52])) .pipe(mutate_is_weeks_post('post_start_date', 'trn_dt', weeks=[2, 4, 52])) .group_by("campaign_id", "modality") .agg( s.across( selector=s.matches("is_pre|is_post"), func=lambda col: _.net_spend_amt.sum(where=col), # 可选:统一重命名结果列,添加后缀标识求和结果 names="{0}_sales" ) ) )
方案说明
- 原尝试失败原因:直接引用
df.net_spend_amt会绑定到原始表对象,无法适配分组后的上下文,而lambda函数可以动态接收每个选中的布尔列col,确保条件筛选与当前列关联。 - 逻辑分离:之前通过
mutate生成布尔列的代码负责定义时间窗口筛选规则,聚合时的across专注于基于布尔列的求和逻辑,实现了职责分离。 - 可选优化:通过
names参数可以统一修改聚合结果的列名,让输出更易读(例如将is_pre2w转为is_pre2w_sales)。
内容的提问来源于stack exchange,提问作者Mark Druffel
相关产品推荐
相关产品推荐

