如何用Python统计上月为Active本月变为Inactive的用户数
统计符合特定状态变更规则的Python实现
核心需求
统计满足以下两个条件的用户数量:
- 当前状态为
Inactive - 该用户变更为
Inactive的前一个月内,状态是Active;若变更前状态为非Active(如Pending),则排除。
基于Pandas的实现(推荐,适合大规模数据)
1. 构造示例数据
先模拟一份用户状态变更数据集,包含user_id(用户ID)、status(状态)、change_date(状态变更日期):
import pandas as pd from datetime import datetime, timedelta data = { 'user_id': ['Alison', 'Alison', 'Bill', 'Bill', 'Charlie', 'Charlie'], 'status': ['Active', 'Inactive', 'Pending', 'Inactive', 'Active', 'Inactive'], 'change_date': [ datetime(2024, 1, 15), datetime(2024, 2, 20), # Alison符合:从Active→Inactive,间隔1个月内 datetime(2024, 1, 10), datetime(2024, 2, 5), # Bill不符合:从Pending→Inactive datetime(2024, 3, 5), datetime(2024, 4, 10) # Charlie符合:从Active→Inactive,间隔1个月内 ] } df = pd.DataFrame(data)
2. 数据预处理
按用户ID和变更日期排序,为每条记录生成「上一条状态」和「上一条变更日期」字段:
# 按用户+日期排序,保证状态变更顺序正确 df = df.sort_values(by=['user_id', 'change_date']) # 分组生成前序状态和日期列 df['prev_status'] = df.groupby('user_id')['status'].shift(1) df['prev_change_date'] = df.groupby('user_id')['change_date'].shift(1)
3. 筛选符合条件的用户
先获取每个用户的最新状态记录(判断当前状态),再筛选符合规则的用户:
# 获取每个用户的最新状态 latest_status = df.groupby('user_id').last().reset_index() # 筛选逻辑:最新状态为Inactive + 前序状态为Active + 两次变更间隔≤30天(近似一个月) qualified = latest_status[ (latest_status['status'] == 'Inactive') & (latest_status['prev_status'] == 'Active') & (latest_status['change_date'] - latest_status['prev_change_date'] <= timedelta(days=30)) ] # 统计数量 qualified_count = len(qualified) print(f"符合条件的用户数:{qualified_count}") # 输出:2
纯Python基础实现(无第三方库)
如果不需要Pandas,用基础Python处理列表数据:
from datetime import datetime, timedelta # 示例数据:(用户ID, 状态, 变更日期) user_records = [ ('Alison', 'Active', datetime(2024, 1, 15)), ('Alison', 'Inactive', datetime(2024, 2, 20)), ('Bill', 'Pending', datetime(2024, 1, 10)), ('Bill', 'Inactive', datetime(2024, 2, 5)), ('Charlie', 'Active', datetime(2024, 3, 5)), ('Charlie', 'Inactive', datetime(2024, 4, 10)) ] # 按用户分组并排序 user_groups = {} for record in user_records: user_id = record[0] user_groups.setdefault(user_id, []).append(record) # 每组按变更日期排序 for uid in user_groups: user_groups[uid].sort(key=lambda x: x[2]) # 统计符合条件的用户 count = 0 for uid, records in user_groups.items(): latest = records[-1] # 跳过当前状态不是Inactive的用户 if latest[1] != 'Inactive': continue # 跳过只有一条状态记录的用户(无前置状态) if len(records) < 2: continue prev_record = records[-2] # 检查前置状态和时间间隔 if prev_record[1] == 'Active' and (latest[2] - prev_record[2] <= timedelta(days=30)): count += 1 print(f"符合条件的用户数:{count}") # 输出:2
内容的提问来源于stack exchange,提问作者Alison Gass
相关产品推荐
相关产品推荐

