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

Python实现缺口起止日期自动标记(含多周期处理)的技术问询

Python数据处理解决方案

需求回顾

  • 按ID+sub_id分组,提取缺口首次出现的extraction_date作为start_date
  • 当Condition为"Y"时,将对应extraction_date填充为end_date,否则为"N/A"
  • 支持同一分组多周期缺口(关闭后重新开启),兼容未来新增数据

实现代码

import pandas as pd

# 1. 准备示例数据(实际使用时可替换为读取CSV/Excel,如pd.read_csv("data.csv"))
data = {
    "ID": [100, 100, 100, 101, 101, 100, 100, 101, 101, 102, 102],
    "sub_id": ["x", "x", "y", "z", "z", "x", "x", "z", "z", "w", "w"],
    "Condition": ["N", "Y", "Y", "N", "N", "N", "Y", "N", "Y", "N", "Y"],
    "extraction_date": ["2024-01-15", "2024-02-01", "2024-02-01", "2024-02-01", "2024-03-16",
                       "2024-03-16", "2024-04-10", "2024-04-10", "2024-05-15", "2024-05-15", "2024-06-15"]
}
df = pd.DataFrame(data)

# 2. 转换日期格式(确保日期可排序)
df["extraction_date"] = pd.to_datetime(df["extraction_date"])

# 3. 按ID+sub_id分组,每组内按日期排序(关键:保证时间顺序正确)
df = df.sort_values(by=["ID", "sub_id", "extraction_date"]).reset_index(drop=True)

# 4. 标记每个缺口周期
def mark_cycles(group):
    # 初始化周期标记
    group["cycle"] = 0
    current_cycle = 1
    # 处理第一行
    group.loc[group.index[0], "cycle"] = current_cycle
    # 遍历后续行
    for i in range(1, len(group)):
        prev_condition = group.iloc[i-1]["Condition"]
        curr_condition = group.iloc[i]["Condition"]
        # 当从Y切换到N时,开启新周期
        if prev_condition == "Y" and curr_condition == "N":
            current_cycle += 1
        group.loc[group.index[i], "cycle"] = current_cycle
    return group

df = df.groupby(["ID", "sub_id"], group_keys=False).apply(mark_cycles)

# 5. 计算start_date:每个周期的第一个日期
df["start_date"] = df.groupby(["ID", "sub_id", "cycle"])["extraction_date"].transform("first")

# 6. 计算end_date:Condition为Y时填当前日期,否则为"N/A"
df["end_date"] = df.apply(lambda row: row["extraction_date"] if row["Condition"] == "Y" else "N/A", axis=1)

# 7. 转换日期格式为字符串(与示例输出一致)
df["start_date"] = df["start_date"].dt.strftime("%Y-%m-%d")
df["end_date"] = df["end_date"].apply(lambda x: x.strftime("%Y-%m-%d") if isinstance(x, pd.Timestamp) else x)
df["extraction_date"] = df["extraction_date"].dt.strftime("%Y-%m-%d")

# 8. 调整列顺序(与示例输出一致)
df = df[["ID", "sub_id", "Condition", "extraction_date", "start_date", "end_date"]]

print(df)

代码说明

  1. 日期转换与排序:先把日期转为datetime类型并排序,确保每组内数据按时间顺序处理,这是多周期处理的基础。
  2. 周期标记:通过分组遍历,识别从"Y"到"N"的切换点,为每个新缺口周期分配唯一标记,同一周期的记录会被归为一组。
  3. start_date计算:利用transform("first")提取每个周期的第一个日期,自动填充到该周期的所有行。
  4. end_date计算:简单条件判断,仅当Condition为"Y"时填充当前日期,否则显示"N/A"。
  5. 格式统一:最后把日期转回字符串格式,与示例输出一致。

兼容性说明

  • 新增数据时,只需将新数据追加到原DataFrame,重复执行上述代码即可自动识别新的周期,无需修改逻辑。
  • 支持任意数量的ID+sub_id组合,以及任意次数的缺口开启/关闭循环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 21:35:05