如何在 Pandas 中按分组标记首个满足条件的行

发布时间 - 2026-01-12 00:00:00    点击率:

本文介绍如何使用 pandas 高效识别并标记每个分组中首次出现指定字符(如 `'y'`)所在行的对应日期,适用于客户行为分析、事件首触点追踪等场景。

在数据分析中,常需定位每个用户(或类别)首次满足某条件的记录,例如:每位客户第一次回复“Y”的日期。Pandas 提供了简洁而强大的向量化方法,无需循环或 apply,即可高效实现该目标。

核心思路分为三步:

  1. 构造布尔条件:筛选出 Y/N 列值为 'Y' 的行;
  2. 分组内累计计数:对每组 CUS_NAME,在满足 'Y' 的行上进行 cumsum(),得到每个 'Y' 在其组内的序号(1 表示首次,2 表示第二次……);
  3. 精准标记首行:仅当同时满足“是 'Y'”且“是该组第 1 个 'Y'”时,才填充 BAS_DT,否则设为 NaN。

以下是完整实现代码:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'BAS_DT': ['2025-01-02', '2025-01-03', '2025-01-04', '2025-01-02', '2025-01-03'],
    'CUS_NAME': ['A', 'A', 'A', 'B', 'B'],
    'Y/N': ['Y', 'Y', 'Y', 'N', 'Y'],
    'cum_count': [1, 2, 3, 1, 2]
})

# 步骤 1:标识所有 'Y' 行
cond = df['Y/N'].eq('Y')

# 步骤 2:按 CUS_NAME 分组,对 cond 进行 cumsum → 得到每组内 'Y' 的累计序号
cond1 = cond.groupby(df['CUS_NAME']).cumsum().eq(1)  # 仅保留每组第一个 'Y'

# 步骤 3:用 where() 实现条件赋值 —— 满足 cond & cond1 时取 BAS_DT,否则 NaN
df['occur_date'] = df['BAS_DT'].where(cond & cond1)

print(df)

✅ 输出结果与预期完全一致:

       BAS_DT CUS_NAME Y/N  cum_count  occur_date
0  2025-01-02        A   Y          1  2025-01-02
1  2025-01-03        A   Y          2         NaN
2  2025-01-04        A   Y          3         NaN
3  2025-01-02        B   N          1         NaN
4  2025-01-03        B   Y          2  2025-01-03

? 注意事项与扩展提示

  • where() 是安全的向量化赋值方式,比 np.where() 更直观,且天然支持 NaN 填充;
  • 若需获取全局首个 'Y'(不按组),可直接使用 df.loc[df['Y/N'].eq('Y').idxmax(), 'BAS_DT'];
  • 若数据中存在缺失值(NaN)于 Y/N 列,建议先用 dropna(subset=['Y/N']) 或显式处理,避免 eq('Y') 返回 False 导致误判;
  • 该方法时间复杂度为 O(n),远优于 groupby().apply(lambda x: x[x['Y/N']=='Y'].iloc[0]) 等低效方案。

掌握这一模式后,你可轻松迁移至其他场景:如标记每个产品的首次销售日、每位员工的首次打卡时间、每笔订单的首次支付成功时刻等——只需替换列名与条件即可复用。


# app  # pandas  # 循环  # Lambda  # 事件  # 数据分析  # 首次  # 每组  # 这一  # 第一个  # 只需  # 设为  # 适用于  # 布尔  # 你可  # 可直接 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 高端建站如何打造兼具美学与转化的品牌官网?  如何快速搭建个人网站并优化SEO?  动图在线制作网站有哪些,滑动动图图集怎么做?  JS碰撞运动实现方法详解  javascript中的try catch异常捕获机制用法分析  javascript中的数组方法有哪些_如何利用数组方法简化数据处理  JS弹性运动实现方法分析  EditPlus 正则表达式 实战(3)  大学网站设计制作软件有哪些,如何将网站制作成自己app?  电商网站制作价格怎么算,网上拍卖流程以及规则?  如何快速搭建FTP站点实现文件共享?  如何正确选择百度移动适配建站域名?  Laravel怎么使用Blade模板引擎_Laravel模板继承与Component组件复用【手册】  Python结构化数据采集_字段抽取解析【教程】  Laravel用户认证怎么做_Laravel Breeze脚手架快速实现登录注册功能  如何在云虚拟主机上快速搭建个人网站?  Laravel怎么实现支付功能_Laravel集成支付宝微信支付  Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?  Laravel与Inertia.js怎么结合_使用Laravel和Inertia构建现代单页应用  如何在宝塔面板中修改默认建站目录?  如何在IIS中新建站点并配置端口与物理路径?  北京网站制作的公司有哪些,北京白云观官方网站?  悟空浏览器如何设置小说背景色_悟空浏览器背景色设置【方法】  Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】  重庆市网站制作公司,重庆招聘网站哪个好?  Laravel怎么使用Intervention Image库处理图片上传和缩放  微信小程序 配置文件详细介绍  mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?  Laravel如何使用Seeder填充数据_Laravel模型工厂Factory批量生成测试数据【方法】  Java垃圾回收器的方法和原理总结  iOS验证手机号的正则表达式  Win11怎么修改DNS服务器 Win11设置DNS加速网络【指南】  Laravel PHP版本要求一览_Laravel各版本环境要求对照  Midjourney怎样加参数调细节_Midjourney参数调整技巧【指南】  rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted  PHP 500报错的快速解决方法  如何在建站之星网店版论坛获取技术支持?  EditPlus中的正则表达式 实战(1)  如何登录建站主机?访问步骤全解析  如何快速生成专业多端适配建站电话?  Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】  C语言设计一个闪闪的圣诞树  EditPlus中的正则表达式实战(6)  成都品牌网站制作公司,成都营业执照年报网上怎么办理?  夸克浏览器网页跳转延迟怎么办 夸克浏览器跳转优化  绝密ChatGPT指令:手把手教你生成HR无法拒绝的求职信  Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录  昵图网官网入口 昵图网素材平台官方入口  HTML透明颜色代码在Angular里怎么设置_Angular透明颜色使用指南【详解】  如何用AI帮你把自己的生活经历写成一个有趣的故事?