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

按ID分组检查DataFrame中指定状态是否最终导向sold

问题与解决方案

问题背景

现有如下DataFrame:

id | status
____________
1  | reserved
2  | signed
1  | waiting
1  | signed
3  | waiting
2  | sold
3  | reserved
1  | sold

需要验证假设:状态reserved、waiting、signed最终都会导向sold(允许跳过部分状态,比如id=2直接从signed到sold)。目标是筛选出符合该规则的ID列表或DataFrame,期望输出如下:

id
__
1
2

本人尝试先筛选指定状态的数据,按ID分组获取唯一状态列表,但因可能的状态组合过多,无法逐一过滤,尝试的代码如下:

df = df[df.status.isin(['reserved', 'waiting', 'signed', 'sold'])]

df1 = df.groupby('flat_id')['status'].unique()

df1.where('status'== ['reserved', 'waiting', 'signed', 'sold']
or ['reserved', 'waiting', 'sold'] ... )

解决方案

核心逻辑是:每个符合规则的ID,其状态序列最终必须以sold结尾,且所有在sold之前的状态只能是reserved、waiting、signed这三类(允许跳过中间状态)。

方法一:分组后自定义验证函数

先确保数据按ID排序(保证状态顺序是时间先后),再对每个分组做规则校验:

import pandas as pd

# 初始化示例数据
df = pd.DataFrame({
    'id': [1,2,1,1,3,2,3,1],
    'status': ['reserved','signed','waiting','signed','waiting','sold','reserved','sold']
})

# 按id排序,确保状态顺序符合时间逻辑
df = df.sort_values('id').reset_index(drop=True)

def validate_status(group):
    status_seq = group['status'].tolist()
    # 最后一个状态必须是sold
    if status_seq[-1] != 'sold':
        return False
    # 检查所有sold之前的状态都是允许的前置状态
    allowed_pre_states = {'reserved', 'waiting', 'signed'}
    return all(state in allowed_pre_states for state in status_seq[:-1])

# 分组验证,筛选出符合条件的id
valid_ids = df.groupby('id').apply(validate_status)
result = valid_ids[valid_ids].index.to_frame(name='id')

print(result)

运行输出:

id
0   1
1   2

方法二:利用分组聚合简化代码

通过last()获取每个ID的最终状态,同时校验所有非最终状态的合法性:

# 筛选最终状态为sold的ID
final_is_sold = df.groupby('id')['status'].last() == 'sold'
# 筛选所有非sold状态都属于允许列表的ID
pre_states_valid = df[df['status'] != 'sold'].groupby('id')['status'].apply(lambda x: x.isin(['reserved', 'waiting', 'signed']).all())
# 取两个条件的交集,得到符合规则的ID
valid_ids = final_is_sold & pre_states_valid
result = valid_ids[valid_ids].index.to_frame(name='id')

print(result)

这个方法代码更简洁,结果和方法一完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 15:27:21