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

基于月份限制拆分Pandas DataFrame时长数据并生成新行

拆分跨月时长至单月范围的Pandas实现

需求说明

给定包含起始时间(datetime列)和小时级时长(duration列)的Pandas DataFrame,需将跨月的时长拆分为单月内的独立记录:若某条记录的时长超出起始时间所在月份的剩余小时数,则生成新行,新行起始时间设为次月零点,剩余时长填入对应行。

示例数据

原始DataFrame

datetime  duration
0  20-01-2001 03:00       960
1  01-05-2001 19:00        18

目标输出DataFrame

datetime  duration
0  2001-01-20 03:00:00       285
1  2001-02-01 00:00:00       672
2  2001-03-01 00:00:00         3
3  2001-05-01 19:00:00        18

实现代码

import pandas as pd
from dateutil.relativedelta import relativedelta

# 构建原始数据
df = pd.DataFrame({
    'datetime': ['20-01-2001 03:00', '01-05-2001 19:00'],
    'duration': [960, 18]
})

# 转换datetime列为标准时间格式(注意原始格式是日-月-年)
df['datetime'] = pd.to_datetime(df['datetime'], format='%d-%m-%Y %H:%M')

def split_monthly_records(row):
    start_time = row['datetime']
    remaining_hours = row['duration']
    output_records = []
    
    while remaining_hours > 0:
        # 计算次月零点时间,以此为边界计算当月剩余小时数
        next_month_start = (start_time + relativedelta(months=1)).replace(day=1, hour=0, minute=0)
        available_hours = (next_month_start - start_time).total_seconds() / 3600
        
        if remaining_hours <= available_hours:
            # 剩余时长未跨月,直接记录
            output_records.append({
                'datetime': start_time,
                'duration': remaining_hours
            })
            remaining_hours = 0
        else:
            # 时长跨月,先记录当月可容纳的时长,更新剩余时长和起始时间
            output_records.append({
                'datetime': start_time,
                'duration': available_hours
            })
            remaining_hours -= available_hours
            start_time = next_month_start
    
    return output_records

# 应用拆分函数并展开结果
result_df = df.apply(split_monthly_records, axis=1).explode().apply(pd.Series).reset_index(drop=True)
# 将时长转为整数(匹配示例输出格式)
result_df['duration'] = result_df['duration'].astype(int)

print(result_df)

关键逻辑说明

  1. 时间格式转换:确保datetime列是Pandas可识别的datetime64类型,后续时间计算依赖此类型。
  2. 单条记录拆分循环:
    • 计算当前起始时间到当月结束的剩余小时数(以次月零点为边界)。
    • 根据剩余时长与当月可用小时数的大小关系,决定是直接记录还是拆分出当月部分,更新剩余时长和起始时间后继续循环。
  3. 结果展开:用explode将每行生成的记录列表展开为多行,最终整理成目标DataFrame格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 23:25:19