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

Pandas:如何按日期拆分跨天的DataFrame时间区间行?

拆分跨天时间区间的DataFrame行

需求说明

需要将DataFrame中跨天的时间区间拆分为按天分段的行,每行对应当日的时间区间,并计算对应的时间差。

原始DataFrame

Tiempo_iniValorTiempo_diffTiempo_finCambio
2018-01-02 21:51:4710 days 12:46:302018-01-03 10:38:17True
2018-01-03 22:11:1710 days 07:46:002018-01-04 05:57:17True
2018-01-04 22:22:1710 days 08:38:002018-01-05 07:00:17True
2018-01-05 07:01:1711 days 13:01:302018-01-06 20:02:47True
2018-01-06 20:30:1710 days 04:27:002018-01-07 00:57:17True

期望拆分效果

以第一行为例,需拆分为以下两行:

Tiempo_iniValorTiempo_finTiempo_diffCambio
2018-01-02 21:51:4712018-01-03 00:00:000 days 02:08:13True
2018-01-03 00:00:0012018-01-03 10:38:170 days 10:38:17True

尝试的代码及问题

以下是尝试实现的代码,但循环中错误修改了结束时间,导致拆分逻辑混乱:

nuevos_registros = []

for index, row in df.iterrows():
    if row['Cambio'] == True:

        tiempo_ini = row['Tiempo_ini']
        tiempo_diff = row['Tiempo_diff']
        tiempo_fin = row['Tiempo_fin']

        
        while tiempo_diff > timedelta(seconds=0):
            
            tiempo_fin_original = row['Tiempo_fin']
            tiempo_diff_original = tiempo_diff
            tiempo_diff = ((tiempo_ini + timedelta(days=1)).replace(hour=0, minute=0, second=0) - tiempo_ini)

            nuevo_registro = {
                "Tiempo_ini": tiempo_ini,
                "Valor": row["Valor"],
                "Tiempo_fin": (tiempo_ini + timedelta(days=1)).replace(hour=0, minute=0, second=1),
                "Tiempo_diff": ((tiempo_ini + timedelta(days=1)).replace(hour=0, minute=0, second=0) - tiempo_ini),
                "Cambio": True
            }
            nuevos_registros.append(nuevo_registro)

            tiempo_diff = tiempo_diff_original - tiempo_diff
            tiempo_ini = (tiempo_ini + timedelta(days=1)).replace(hour=0, minute=0, second=0)
            tiempo_fin = tiempo_fin_original

        
    
    else:
        nuevo_registro = {
        "Tiempo_ini": row['Tiempo_ini'],
        "Valor": row["Valor"],
        "Tiempo_fin": row['Tiempo_fin'],
        "Tiempo_diff": row['Tiempo_diff'],
        "Cambio": False 
        }

        nuevos_registros.append(nuevo_registro)


df_mod = pd.DataFrame(nuevos_registros)

    
df_mod[df_mod['Cambio'] == True].head()

错误输出

Tiempo_iniValorTiempo_finTiempo_diffCambio
2018-01-02 21:51:4712018-01-03 00:00:010 days 02:08:13True
2018-01-03 00:00:0012018-01-04 00:00:011 days 00:00:00True
2018-01-03 22:11:1712018-01-04 00:00:010 days 01:48:43True
2018-01-04 00:00:0012018-01-05 00:00:011 days 00:00:00True
2018-01-04 22:22:1712018-01-05 00:00:010 days 01:37:43True

解决方案

修正后的代码逻辑为:对每一行,逐段生成从当前起始时间到当日结束或原始结束时间的区间,直到覆盖整个原始时间范围:

import pandas as pd
from datetime import timedelta, datetime

def split_cross_day_rows(row):
    if not row['Cambio']:
        return [row.to_dict()]
    
    start = row['Tiempo_ini']
    end = row['Tiempo_fin']
    valor = row['Valor']
    cambio = row['Cambio']
    
    split_rows = []
    current_start = start
    
    while current_start < end:
        # 计算当日结束时间(次日0点)
        day_end = current_start.replace(hour=0, minute=0, second=0) + timedelta(days=1)
        # 取当日结束和原始结束的较小值作为实际结束时间
        actual_end = min(day_end, end)
        # 计算当前区间的时间差
        diff = actual_end - current_start
        
        split_rows.append({
            'Tiempo_ini': current_start,
            'Valor': valor,
            'Tiempo_fin': actual_end,
            'Tiempo_diff': diff,
            'Cambio': cambio
        })
        
        # 更新起始时间为当前区间的结束时间
        current_start = actual_end
    
    return split_rows

# 应用拆分函数并展平结果
nuevos_registros = []
for _, row in df.iterrows():
    nuevos_registros.extend(split_cross_day_rows(row))

df_mod = pd.DataFrame(nuevos_registros)
print(df_mod[df_mod['Cambio'] == True])

正确输出

Tiempo_iniValorTiempo_finTiempo_diffCambio
2018-01-02 21:51:4712018-01-03 00:00:000 days 02:08:13True
2018-01-03 00:00:0012018-01-03 10:38:170 days 10:38:17True
2018-01-03 22:11:1712018-01-04 00:00:000 days 01:48:43True
2018-01-04 00:00:0012018-01-04 05:57:170 days 05:57:17True
2018-01-04 22:22:1712018-01-05 00:00:000 days 01:37:43True
2018-01-05 00:00:0012018-01-05 07:00:170 days 07:00:17True
2018-01-05 07:01:1712018-01-06 00:00:000 days 16:58:43True
2018-01-06 00:00:0012018-01-06 20:02:470 days 20:02:47True
2018-01-06 20:30:1712018-01-07 00:00:000 days 03:29:43True
2018-01-07 00:00:0012018-01-07 00:57:170 days 00:57:17True

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 05:39:50