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

基于Dataframe计算日期区间周数及各周天数的实现需求

拆分日期区间生成周相关字段的DataFrame处理方案

需求说明

我们需要处理一个包含ID、RID、PID、check_in、check_out字段的DataFrame,为每条记录计算日期区间内的周相关信息,新增以下4个字段:

  • Weekite:区间覆盖的周数
  • Weekstart:区间起始日期所在周的周一(周起始日,样例中以周一为一周开端)
  • Weekgrp:与Weekstart一致,用作周分组标识
  • Days:区间内的实际天数(按小时差计算的完整天数)

输入输出样例

输入DataFrame

IDRIDPIDcheck_incheck_out
102401113-08-2014 9.3014-08-2014 9.30
102402116-08-2014 9.3017-08-2014 9.30
102403218-09-2012 9.3025-09-2012 9.30
102404125-09-2012 9.3030-09-2012 9.30
102405127-01-2015 22.3027-02-2015 20.30

期望输出DataFrame

IDRIDPIDcheck_incheck_outWeekiteWeekstartWeekgrpDays
102401113-08-2014 9.3014-08-2014 9.30110-08-201410-08-20141
102402116-08-2014 9.3017-08-2014 9.30110-08-201410-08-20141
102403218-09-2012 9.3025-09-2012 9.30117-09-201217-09-20127
102404125-09-2012 9.3030-09-2012 9.30224-09-201224-09-20125
102405127-01-2015 22.3027-02-2015 20.30526-01-201526-01-201530

解决方案(Python + Pandas)

下面是完整的代码实现,每一步都做了详细注释,方便理解:

import pandas as pd

# 1. 构造输入DataFrame(如果是从文件读取,替换成pd.read_csv等方法即可)
data = {
    "ID": [10240, 10240, 10240, 10240, 10240],
    "RID": [1, 2, 3, 4, 5],
    "PID": [1, 1, 2, 1, 1],
    "check_in": ["13-08-2014 9.30", "16-08-2014 9.30", "18-09-2012 9.30", "25-09-2012 9.30", "27-01-2015 22.30"],
    "check_out": ["14-08-2014 9.30", "17-08-2014 9.30", "25-09-2012 9.30", "30-09-2012 9.30", "27-02-2015 20.30"]
}
df = pd.DataFrame(data)

# 2. 转换日期格式:把原格式的.替换成:,再解析为datetime类型
df["check_in"] = pd.to_datetime(df["check_in"].str.replace(".", ":"), format="%d-%m-%Y %H:%M")
df["check_out"] = pd.to_datetime(df["check_out"].str.replace(".", ":"), format="%d-%m-%Y %H:%M")

# 3. 计算Days字段:通过时间差的总秒数转换为天数,取整数部分
df["Days"] = (df["check_out"] - df["check_in"]).dt.total_seconds() / (24 * 3600)
df["Days"] = df["Days"].astype(int)

# 4. 计算Weekstart和Weekgrp:取check_in所在周的周一作为周起始日
# 注:pandas中dt.weekday的0代表周一,6代表周日;如果需要以周日为起始,可调整offset
df["Weekstart"] = df["check_in"] - pd.to_timedelta(df["check_in"].dt.weekday, unit="D")
# 格式化为dd-mm-yyyy的字符串格式
df["Weekstart"] = df["Weekstart"].dt.strftime("%d-%m-%Y")
df["Weekgrp"] = df["Weekstart"]  # 与Weekstart保持一致

# 5. 计算Weekite:计算区间覆盖的总周数
# 方法:先取check_out所在周的周一,再和check_in的周起始日计算间隔周数,最后加1
check_out_weekstart = df["check_out"] - pd.to_timedelta(df["check_out"].dt.weekday, unit="D")
df["Weekite"] = ((check_out_weekstart - pd.to_datetime(df["Weekstart"])).dt.days // 7) + 1

# 6. 调整列顺序,与期望输出对齐
output_cols = ["ID", "RID", "PID", "check_in", "check_out", "Weekite", "Weekstart", "Weekgrp", "Days"]
df = df[output_cols]

# 可选:把日期列转回原字符串格式(如果不需要datetime类型的话)
df["check_in"] = df["check_in"].dt.strftime("%d-%m-%Y %H.%M")
df["check_out"] = df["check_out"].dt.strftime("%d-%m-%Y %H.%M")

# 打印结果
print(df)

关键步骤解释

  • 日期格式转换:原数据里的小时分钟用.分隔,先替换成标准的:才能被pandas正确解析为时间类型。
  • Days计算:通过时间差的总秒数除以一天的秒数,得到精确的天数,再转成整数确保是完整天数。
  • Weekstart/Weekgrp:用当前日期减去对应的星期几的天数,快速定位到该周的周一;如果需要以周日为周起始,只需要调整offset即可(比如df["check_in"] - pd.to_timedelta(df["check_in"].dt.dayofweek + 1, unit="D"))。
  • Weekite计算:通过两个周起始日的间隔天数除以7,得到周数差,再加1就是区间覆盖的总周数,能准确跨周的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:21:34