如何基于address_id和降序日期为DataFrame添加mover标记?
为Pandas DataFrame添加'mover'列的解决方案
原代码的语法错误分析
你提供的代码存在两个核心问题:
- 在
groupby调用中尝试使用['my_date']=descending的赋值语法,这是无效的,无法在该上下文直接指定排序方式。 - 括号匹配错误,导致Python无法解析代码结构。
规则梳理
根据需求,mover标记的判定逻辑可简化为:
- 仅当该地址曾使用过Verizon,且最终未使用Verizon时,
mover=True - 其他所有情况(从未使用Verizon、最终使用Verizon),
mover=False
分步实现代码
import pandas as pd import numpy as np # 原始数据构建DataFrame details = { 'address_id': [111,111,111,111,111,111,222,222,222,222,222,222,333,333,333,333,333,333,444,444,444,444,444,444,555,555,555,555,555,555,777,777,777], 'my_company':['Comcast','Verizon','Other','Other','Comcast','Comcast','Spectrum','Spectrum','Spectrum','Spectrum','Spectrum','Spectrum','Verizon','Verizon','Verizon','Verizon','Verizon','Verizon','Spectrum','Spectrum','Spectrum','Spectrum','Verizon','Spectrum','Spectrum','Spectrum','Spectrum','Spectrum','Verizon','Other','Verizon','Comcast','Comcast'], 'my_date':['2022-01-24','2022-02-21','2022-03-28','2022-04-25','2022-05-23','2022-06-27','2022-01-24','2022-02-21','2022-03-28','2022-04-25','2022-05-23','2022-06-27','2022-01-24','2022-02-21','2022-03-28','2022-04-25','2022-05-23','2022-06-27','2022-01-24','2022-02-21','2022-03-28','2022-04-25','2022-05-23','2022-06-27','2022-01-24','2022-02-21','2022-03-28','2022-04-25','2022-05-23','2022-06-27','2022-01-24','2022-02-21','2022-03-28'] } df = pd.DataFrame(details) # 1. 将日期列转换为datetime类型,确保排序正确性 df['my_date'] = pd.to_datetime(df['my_date']) # 2. 按地址ID和日期排序,保证每组内的记录按时间顺序排列 df_sorted = df.sort_values(['address_id', 'my_date']) # 3. 按地址分组,计算两个关键指标:是否使用过Verizon、最后使用的运营商 address_metrics = df_sorted.groupby('address_id').agg( has_verizon=('my_company', lambda x: 'Verizon' in x.unique()), last_company=('my_company', 'last') ) # 4. 根据规则计算mover标记 address_metrics['mover'] = address_metrics['has_verizon'] & (address_metrics['last_company'] != 'Verizon') # 5. 将mover标记映射回原始DataFrame df['mover'] = df['address_id'].map(address_metrics['mover']) # 查看结果 print(df)
结果说明
- address_id 111:曾使用Verizon,最终使用Comcast →
mover=True - address_id 222:从未使用Verizon →
mover=False - address_id 333:始终使用Verizon →
mover=False - address_id 444:曾使用Verizon,最终使用Spectrum →
mover=True - address_id 555:曾使用Verizon,最终使用Other →
mover=True - address_id 777:曾使用Verizon,最终使用Comcast →
mover=True
内容的提问来源于stack exchange,提问作者ASH
相关产品推荐
相关产品推荐

