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

基于多列创建条件标记:按连续三月completed值判定用户状态

问题:基于DataFrame的用户违约状态判定

判定规则

若某Id存在连续3个月的completed列值为0,则标记为defaulter;否则标记为non_defaulter。

输入DataFrame

Id       Month        Year       scheduled         completed
A         Jan         2021           0                 0
A         Feb         2021           1                 0
A         mar         2021           0                 0
B         June        2021           0                 1
B         July        2021           0                 1
B         Aug         2021           0                 1
B         Sep         2021           0                 1
C         Nov         2021           1                 0
C         Dec         2021           1                 0
C         Jan         2022           1                 0
C         Feb         2022           1                 0

预期输出

Id           status
 A          defaulter
 B          non_defaulter
 C          defaulter

解决方案(Pandas实现)

核心步骤:先统一日期格式并按时间排序,再分组计算连续0的区间长度,最后根据长度判定状态。

代码实现:

import pandas as pd

# 构造输入DataFrame
df = pd.DataFrame({
    'Id': ['A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C'],
    'Month': ['Jan', 'Feb', 'mar', 'June', 'July', 'Aug', 'Sep', 'Nov', 'Dec', 'Jan', 'Feb'],
    'Year': [2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2022, 2022],
    'scheduled': [0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1],
    'completed': [0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0]
})

# 统一月份格式并转换为日期
df['Month'] = df['Month'].str.capitalize()
df['date'] = pd.to_datetime(df['Month'] + ' ' + df['Year'].astype(str), format='%b %Y')

# 按Id分组并按日期排序
df = df.sort_values(['Id', 'date']).reset_index(drop=True)

# 标记completed=0的行,并生成连续区间分组ID
df['is_zero'] = df['completed'] == 0
df['zero_group'] = df.groupby('Id')['is_zero'].apply(lambda x: x.ne(x.shift()).cumsum())

# 统计每个连续0区间的长度
zero_lengths = df[df['is_zero']].groupby(['Id', 'zero_group']).size().reset_index(name='count')

# 判定每个Id的状态
status_df = zero_lengths.groupby('Id')['count'].max().reset_index()
status_df['status'] = status_df['count'].apply(lambda x: 'defaulter' if x >= 3 else 'non_defaulter')

# 补全无连续0的Id状态(如B)
all_ids = df['Id'].unique()
status_df = status_df.set_index('Id').reindex(all_ids).fillna('non_defaulter').reset_index()

# 输出结果
print(status_df[['Id', 'status']])

代码说明

  1. 日期处理:将月份和年份合并为可排序的datetime对象,确保跨年度的连续月份(如2021年12月→2022年1月)能被正确识别。
  2. 连续区间标记:通过ne(x.shift()).cumsum()生成每个连续0序列的分组ID,方便统计区间长度。
  3. 状态判定:取每个Id的最长连续0区间长度,≥3则标记为defaulter;无连续0的Id直接标记为non_defaulter。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:15:54