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

按事件前后分组行序列:基于DataFrame提取c-i-c检查注射序列

提取DataFrame中的「检查-注射-检查(c-i-c)」序列集合

我来帮你搞定这个提取c-i-c序列的问题!针对你给出的患者检查和注射数据,咱们可以用Pandas一步步实现需求,而且完全支持将前一个序列的后置检查作为下一个序列的前置检查。

步骤1:准备数据并格式化

首先咱们把原始数据转换成标准的Pandas DataFrame,同时确保日期列是datetime格式,方便后续排序:

import pandas as pd

# 原始数据
raw_data = [
    ["1,d", "2016-01-25", 122, "c"],
    ["1,d", "2016-04-26", 213, "i"],
    ["1,d", "2016-05-23", 274, "c"],
    ["1,d", "2016-08-31", 201, "c"],
    ["1,d", "2016-10-25", 223, "i"],
    ["3,s", "2015-05-26", 123, "c"],
    ["3,s", "2015-07-01", 450, "i"],
    ["3,s", "2015-07-21", 234, "c"],
    ["3,s", "2016-01-13", 345, "i"],
    ["3,s", "2016-02-22", 278, "c"],
]

# 转换为DataFrame并处理日期
df = pd.DataFrame(raw_data, columns=["Pat", "Date", "ID", "Visit"])
df["Date"] = pd.to_datetime(df["Date"])

步骤2:按患者分组并排序

因为序列是按时间顺序生成的,所以必须先按患者分组,再对每组内的事件按日期升序排列:

# 分组并排序,确保每个患者的事件按时间先后排列
sorted_df = df.groupby("Pat", group_keys=False).apply(lambda x: x.sort_values("Date")).reset_index(drop=True)

步骤3:定位符合条件的c-i-c序列

咱们可以通过移位操作快速找到每个事件的前后事件,然后筛选出中间是注射(i)、前后都是检查(c)的节点——这些节点就是c-i-c序列的核心,再提取对应的前后检查事件即可:

# 为每个事件添加前一个和后一个Visit类型的列
sorted_df["prev_visit"] = sorted_df.groupby("Pat")["Visit"].shift(1)
sorted_df["next_visit"] = sorted_df.groupby("Pat")["Visit"].shift(-1)

# 筛选出符合c-i-c结构的中间注射事件
valid_injections = sorted_df[(sorted_df["Visit"] == "i") 
                             & (sorted_df["prev_visit"] == "c") 
                             & (sorted_df["next_visit"] == "c")]

# 提取完整的c-i-c序列
sequence_list = []
for idx, injection_row in valid_injections.iterrows():
    patient = injection_row["Pat"]
    # 生成唯一的序列ID
    seq_id = f"{patient}_seq_{len(sequence_list)+1}"
    
    # 提取前置检查、注射、后置检查的行数据
    pre_check = sorted_df.loc[idx-1].to_dict()
    injection = injection_row.to_dict()
    post_check = sorted_df.loc[idx+1].to_dict()
    
    # 为每个事件添加序列ID和角色标记
    sequence_list.append({**pre_check, "Seq_ID": seq_id, "Seq_Role": "前置检查"})
    sequence_list.append({**injection, "Seq_ID": seq_id, "Seq_Role": "注射"})
    sequence_list.append({**post_check, "Seq_ID": seq_id, "Seq_Role": "后置检查"})

# 转换为结果DataFrame并调整列顺序
result_df = pd.DataFrame(sequence_list)
result_df = result_df[["Seq_ID", "Pat", "Date", "ID", "Visit", "Seq_Role"]]

最终结果

运行上述代码后,result_df就包含了所有符合要求的c-i-c序列:

Seq_ID   Pat       Date   ID Visit Seq_Role
0  1,d_seq_1  1,d 2016-01-25  122     c   前置检查
1  1,d_seq_1  1,d 2016-04-26  213     i     注射
2  1,d_seq_1  1,d 2016-05-23  274     c   后置检查
3  3,s_seq_1  3,s 2015-05-26  123     c   前置检查
4  3,s_seq_1  3,s 2015-07-01  450     i     注射
5  3,s_seq_1  3,s 2015-07-21  234     c   后置检查
6  3,s_seq_2  3,s 2015-07-21  234     c   前置检查
7  3,s_seq_2  3,s 2016-01-13  345     i     注射
8  3,s_seq_2  3,s 2016-02-22  278     c   后置检查

可以看到,患者3,s的第二个序列复用了第一个序列的后置检查作为前置检查,完美符合你的需求!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:27:41