如何基于分组内历史状态值填充Python二进制列?
解决方案:基于ID生命周期状态填充二进制列
需求回顾
已将DataFrame按id和date升序排序,需实现:
- 若当前行
status为4或6,且该id在此之前的历史记录中出现过状态2或3,则binary赋值为1 - 其余情况赋值为0
示例中仅ID 4556的对应行需设为1,其余为0。
问题分析
原代码使用isin()仅做静态值匹配,未结合分组和时间维度的累积校验,无法判断当前行之前的历史状态,导致结果错误。
修正实现
利用Pandas的分组(groupby)和累积计算(cummax)实现时间维度的状态校验:
import pandas as pd import numpy as np from datetime import datetime today = datetime.today().strftime('%Y-%m-%d') frame = pd.DataFrame({ 'id': [1245, 4556, 2345, 4556, 1248, 4556, 4556], 'status': [1,2,4,5,6, 3, 4], 'date': ['2022-07-01', '2022-03-12', '2022-04-20', '2022-02-02', '2022-01-03', '2022-05-03', '2022-07-01'] }) # 按id和date升序排序,确保时间顺序正确 frame_ordered = frame.sort_values(['id','date'], ascending=True) # 1. 按id分组,标记当前行及之前是否出现过状态2或3 frame_ordered['has_prev_2_3'] = frame_ordered.groupby('id')['status'].transform( lambda x: x.isin([2,3]).cummax() ) # 2. 标记当前状态是否为4或6 current_status_valid = frame_ordered['status'].isin([4,6]) # 3. 结合两个条件生成binary列 frame_ordered['binary'] = np.where(current_status_valid & frame_ordered['has_prev_2_3'], 1, 0) print(frame_ordered)
代码解释
groupby('id')['status'].transform(lambda x: x.isin([2,3]).cummax()):按ID分组后,对每个ID的状态序列做累积最大值计算——只要之前出现过2或3,从该行开始往后的has_prev_2_3都会保持为True,精准实现时间维度的历史状态校验。current_status_valid:直接判断当前行状态是否符合4或6的要求。- 最后用
np.where结合两个条件,为binary列赋值。
输出结果
运行后,ID 4556中状态为4的行(2022-07-01)会被赋值为1,其余行均为0,完全符合需求。
内容的提问来源于stack exchange,提问作者NoaMi
相关产品推荐
相关产品推荐

