当前位置:首页>python>18_Python数据分析:时间差 (Timedelta)

18_Python数据分析:时间差 (Timedelta)

  • 2026-09-08 19:46:59
18_Python数据分析:时间差 (Timedelta)

Python数据分析:时间差 (Timedelta)

1. 核心知识点概述

Timedelta表示两个时间之间的差值,是时间序列分析中的重要概念:

  • Timedelta
    : 表示时间间隔,如2天、3小时等。
  • to_timedelta()
    : 将字符串或数字转换为Timedelta。
  • 时间差运算
    : 支持加减乘除等运算。
  • 频率转换
    : 在不同时间单位间转换。

关键参数说明

  • days
    : 天数。
  • hours
    : 小时数。
  • minutes
    : 分钟数。
  • seconds
    : 秒数。
  • unit
    : 转换时的单位指定。

2. 示例代码

2.1 准备数据

In [1]:

import pandas as pd
import numpy as np
from datetime import datetime, timedelta
print("Pandas Timedelta功能演示")
print("=" * 40)
Pandas Timedelta功能演示
========================================

2.2 创建Timedelta

多种方式创建时间差对象。

In [2]:

# 使用字符串创建
td1 = pd.Timedelta('2 days')
td2 = pd.Timedelta('1 days 2 hours 30 minutes')
td3 = pd.Timedelta('3W')  # 3周
print("使用字符串创建Timedelta:")
print(f"2天: {td1}")
print(f"1天2小时30分: {td2}")
print(f"3周: {td3}")
# 使用关键字参数创建
td4 = pd.Timedelta(days=5, hours=3, minutes=30)
td5 = pd.Timedelta(weeks=2, days=1)
print("\n使用关键字参数创建:")
print(f"5天3小时30分: {td4}")
print(f"2周1天: {td5}")
# 使用to_timedelta批量转换
td_list = pd.to_timedelta(['1 days', '2 days', '3 days', '4 days'])
print("\n批量转换:")
print(td_list)
使用字符串创建Timedelta:
2天: 2 days 00:00:00
1天2小时30分: 1 days 02:30:00
3周: 21 days 00:00:00
使用关键字参数创建:
5天3小时30分: 5 days 03:30:00
2周1天: 15 days 00:00:00
批量转换:
TimedeltaIndex(['1 days', '2 days', '3 days', '4 days'], dtype='timedelta64[ns]', freq=None)

2.3 Timedelta属性

获取时间差的各个组成部分。

In [3]:

td = pd.Timedelta(days=5, hours=3, minutes=30, seconds=45)
print(f"Timedelta: {td}")
print(f"\n各组成部分:")
print(f"总天数: {td.days}")
print(f"总秒数: {td.total_seconds()}")
print(f"总小时数: {td.total_seconds() / 3600:.2f}")
# 使用components获取详细分解
print(f"\n详细分解:")
print(f"components: {td.components}")
print(f"天数: {td.components.days}")
print(f"小时: {td.components.hours}")
print(f"分钟: {td.components.minutes}")
print(f"秒: {td.components.seconds}")
# 使用属性访问
print(f"\n属性访问:")
print(f"to_timedelta64: {td.to_timedelta64()}")  # numpy timedelta64
print(f"value: {td.value}")  # 纳秒数
Timedelta: 5 days 03:30:45
各组成部分:
总天数: 5
总秒数: 444645.0
总小时数: 123.51
详细分解:
components: Components(days=5, hours=3, minutes=30, seconds=45, milliseconds=0, microseconds=0, nanoseconds=0)
天数: 5
小时: 3
分钟: 30
秒: 45
属性访问:
to_timedelta64: 444645000000000 nanoseconds
value: 444645000000000

2.4 Timedelta运算

时间差支持各种数学运算。

In [4]:

td1 = pd.Timedelta(days=2)
td2 = pd.Timedelta(days=1, hours=12)
print(f"td1: {td1}")
print(f"td2: {td2}")
# 加减运算
print(f"\n加减运算:")
print(f"td1 + td2: {td1 + td2}")
print(f"td1 - td2: {td1 - td2}")
# 乘除运算
print(f"\n乘除运算:")
print(f"td1 * 2: {td1 * 2}")
print(f"td1 / 2: {td1 / 2}")
print(f"td1 / td2: {td1 / td2:.2f}")  # 比值
# 取绝对值
td_neg = pd.Timedelta(days=-3)
print(f"\n绝对值:")
print(f"原始: {td_neg}")
print(f"abs: {abs(td_neg)}")
td1: 2 days 00:00:00
td2: 1 days 12:00:00
加减运算:
td1 + td2: 3 days 12:00:00
td1 - td2: 0 days 12:00:00
乘除运算:
td1 * 2: 4 days 00:00:00
td1 / 2: 1 days 00:00:00
td1 / td2: 1.33
绝对值:
原始: -3 days +00:00:00
abs: 3 days 00:00:00

2.5 时间戳与Timedelta运算

时间戳加减时间差得到新的时间戳。

In [5]:

ts = pd.Timestamp('2024-03-15 10:00:00')
td = pd.Timedelta(days=3, hours=5)
print(f"原始时间戳: {ts}")
print(f"时间差: {td}")
# 加减运算
print(f"\n时间运算:")
print(f"ts + td: {ts + td}")
print(f"ts - td: {ts - td}")
# 两个时间戳相减得到Timedelta
ts1 = pd.Timestamp('2024-03-15')
ts2 = pd.Timestamp('2024-03-20')
diff = ts2 - ts1
print(f"\nts1: {ts1}")
print(f"ts2: {ts2}")
print(f"ts2 - ts1: {diff}")
print(f"相差天数: {diff.days}")
原始时间戳: 2024-03-15 10:00:00
时间差: 3 days 05:00:00
时间运算:
ts + td: 2024-03-18 15:00:00
ts - td: 2024-03-12 05:00:00
ts1: 2024-03-15 00:00:00
ts2: 2024-03-20 00:00:00
ts2 - ts1: 5 days 00:00:00
相差天数: 5

2.6 Series中的Timedelta

处理包含时间差的Series。

In [6]:

# 创建Timedelta Series
td_series = pd.Series([
    pd.Timedelta(days=1),
    pd.Timedelta(days=2),
    pd.Timedelta(days=3),
    pd.Timedelta(days=4),
    pd.Timedelta(days=5)
])
print("Timedelta Series:")
print(td_series)
# 转换为天数
days = td_series.dt.days
print(f"\n转换为天数:")
print(days)
# 转换为总秒数
seconds = td_series.dt.total_seconds()
print(f"\n转换为总秒数:")
print(seconds)
# 转换为小时
hours = td_series.dt.total_seconds() / 3600
print(f"\n转换为小时:")
print(hours)
Timedelta Series:
0   1 days
1   2 days
2   3 days
3   4 days
4   5 days
dtype: timedelta64[ns]
转换为天数:
0    1
1    2
2    3
3    4
4    5
dtype: int64
转换为总秒数:
0     86400.0
1    172800.0
2    259200.0
3    345600.0
4    432000.0
dtype: float64
转换为小时:
0     24.0
1     48.0
2     72.0
3     96.0
4    120.0
dtype: float64

2.7 实际应用:计算时间间隔

计算事件发生的时间间隔。

In [7]:

# 创建订单数据
orders = pd.DataFrame({
    'order_id': ['A001', 'A002', 'A003', 'A004', 'A005'],
    'order_time': pd.to_datetime(['2024-03-15 09:00', '2024-03-15 10:30', 
                                  '2024-03-15 14:00', '2024-03-15 16:30', 
                                  '2024-03-16 09:00']),
    'delivery_time': pd.to_datetime(['2024-03-15 11:30', '2024-03-15 13:00', 
                                     '2024-03-15 17:00', '2024-03-15 19:00', 
                                     '2024-03-16 12:00'])
})
# 计算配送时间
orders['delivery_duration'] = orders['delivery_time'] - orders['order_time']
print("订单配送时间:")
print(orders)
# 统计配送时间
print(f"\n配送时间统计:")
print(f"平均配送时间: {orders['delivery_duration'].mean()}")
print(f"最短配送时间: {orders['delivery_duration'].min()}")
print(f"最长配送时间: {orders['delivery_duration'].max()}")
# 转换为小时
orders['delivery_hours'] = orders['delivery_duration'].dt.total_seconds() / 3600
print(f"\n配送时间(小时):")
print(orders[['order_id', 'delivery_hours']])
订单配送时间:
  order_id          order_time       delivery_time delivery_duration
0     A001 2024-03-15 09:00:00 2024-03-15 11:30:00   0 days 02:30:00
1     A002 2024-03-15 10:30:00 2024-03-15 13:00:00   0 days 02:30:00
2     A003 2024-03-15 14:00:00 2024-03-15 17:00:00   0 days 03:00:00
3     A004 2024-03-15 16:30:00 2024-03-15 19:00:00   0 days 02:30:00
4     A005 2024-03-16 09:00:00 2024-03-16 12:00:00   0 days 03:00:00
配送时间统计:
平均配送时间: 0 days 02:42:00
最短配送时间: 0 days 02:30:00
最长配送时间: 0 days 03:00:00
配送时间(小时):
  order_id  delivery_hours
0     A001             2.5
1     A002             2.5
2     A003             3.0
3     A004             2.5
4     A005             3.0

2.8 实际应用:用户留存分析

计算用户两次登录之间的时间间隔。

In [8]:

# 创建用户登录数据
logins = pd.DataFrame({
    'user_id': ['U001', 'U001', 'U001', 'U002', 'U002', 'U003', 'U003', 'U003', 'U003'],
    'login_time': pd.to_datetime([
        '2024-03-01', '2024-03-05', '2024-03-15',
        '2024-03-02', '2024-03-10',
        '2024-03-01', '2024-03-03', '2024-03-07', '2024-03-20'
    ])
})
# 按用户排序
logins = logins.sort_values(['user_id', 'login_time'])
# 计算相邻登录间隔
logins['days_since_last'] = logins.groupby('user_id')['login_time'].diff()
print("用户登录间隔:")
print(logins)
# 统计每个用户的平均登录间隔
avg_interval = logins.groupby('user_id')['days_since_last'].mean()
print(f"\n平均登录间隔:")
for user, interval in avg_interval.items():
    if pd.notna(interval):
        print(f"{user}: {interval.days}天")
用户登录间隔:
  user_id login_time days_since_last
0    U001 2024-03-01             NaT
1    U001 2024-03-05          4 days
2    U001 2024-03-15         10 days
3    U002 2024-03-02             NaT
4    U002 2024-03-10          8 days
5    U003 2024-03-01             NaT
6    U003 2024-03-03          2 days
7    U003 2024-03-07          4 days
8    U003 2024-03-20         13 days
平均登录间隔:
U001: 7天
U002: 8天
U003: 6天

2.9 频率转换

将Timedelta转换为不同的时间单位。

In [9]:

td = pd.Timedelta(days=2, hours=5, minutes=30, seconds=45)
print(f"原始Timedelta: {td}")
print(f"\n频率转换:")
print(f"总天数: {td.total_seconds() / 86400:.4f}天")
print(f"总小时: {td.total_seconds() / 3600:.4f}小时")
print(f"总分钟: {td.total_seconds() / 60:.2f}分钟")
print(f"总秒数: {td.total_seconds()}秒")
print(f"总毫秒: {td.total_seconds() * 1000}毫秒")
# 使用floor/ceil/round
print(f"\n取整操作:")
print(f"floor('D'): {td.floor('D')}")  # 向下取整到天
print(f"ceil('h'): {td.ceil('h')}")    # 向上取整到小时
print(f"round('h'): {td.round('h')}")  # 四舍五入到小时
原始Timedelta: 2 days 05:30:45
频率转换:
总天数: 2.2297天
总小时: 53.5125小时
总分钟: 3210.75分钟
总秒数: 192645.0秒
总毫秒: 192645000.0毫秒
取整操作:
floor('D'): 2 days 00:00:00
ceil('h'): 2 days 06:00:00
round('h'): 2 days 06:00:00

2.10 TimedeltaIndex

使用Timedelta作为索引。

In [10]:

# 创建TimedeltaIndex
td_index = pd.timedelta_range(start='0 days', end='10 days', freq='1D')
print("TimedeltaIndex:")
print(td_index)
# 创建Series
td_series = pd.Series(range(len(td_index)), index=td_index)
print(f"\n使用TimedeltaIndex的Series:")
print(td_series)
# 按时间范围筛选
filtered = td_series['2 days':'5 days']
print(f"\n筛选2-5天的数据:")
print(filtered)
# 创建等差时间序列
td_range = pd.timedelta_range(start='0 hours', periods=12, freq='2h')
print(f"\n每2小时的TimedeltaIndex:")
print(td_range)
TimedeltaIndex:
TimedeltaIndex([ '0 days',  '1 days',  '2 days',  '3 days',  '4 days',
                 '5 days',  '6 days',  '7 days',  '8 days',  '9 days',
                '10 days'],
               dtype='timedelta64[ns]', freq='D')
使用TimedeltaIndex的Series:
0 days      0
1 days      1
2 days      2
3 days      3
4 days      4
5 days      5
6 days      6
7 days      7
8 days      8
9 days      9
10 days    10
Freq: D, dtype: int64
筛选2-5天的数据:
2 days    2
3 days    3
4 days    4
5 days    5
Freq: D, dtype: int64
每2小时的TimedeltaIndex:
TimedeltaIndex(['0 days 00:00:00', '0 days 02:00:00', '0 days 04:00:00',
                '0 days 06:00:00', '0 days 08:00:00', '0 days 10:00:00',
                '0 days 12:00:00', '0 days 14:00:00', '0 days 16:00:00',
                '0 days 18:00:00', '0 days 20:00:00', '0 days 22:00:00'],
               dtype='timedelta64[ns]', freq='2h')

3. 常见应用场景总结

  1. 配送时间分析
    :计算订单从下单到送达的时间。
  2. 用户行为分析
    :计算用户两次操作之间的时间间隔。
  3. 设备运行时间
    :计算设备开机到关机的运行时长。
  4. ** SLA监控**:计算服务响应时间是否在SLA范围内。
  5. 会话时长
    :计算用户在线会话的持续时间。
  6. 任务调度
    :计算下次执行时间与当前时间的差值。

最新文章

随机文章