当前位置:首页 > 技术 > 正文内容

Pandas时间序列处理深入解析

访客 技术 2026年6月7日 1

一、时间点数据处理

在数据分析中,时间点数据是最基础的时序数据类型之一,Pandas提供了多种方式来创建和操作这类数据。

1. 使用Timestamp创建时间点

import pandas as pd
import datetime

# 从datetime对象创建
dt_obj = datetime.datetime(2023, 6, 15, 8, 30, 0)
ts1 = pd.Timestamp(dt_obj)

# 从字符串创建
ts2 = pd.Timestamp('2023-06-20')
ts3 = pd.Timestamp('2023-06-20 14:30:00')

print(ts1, type(ts1))
print(ts2)
print(ts3)

2. 使用to_datetime批量转换

# 单值转换
date_str = '2023-07-01'
single_ts = pd.to_datetime(date_str)
print(single_ts, type(single_ts))

# 批量转换生成DatetimeIndex
dates_list = ['2023-07-01', '2023-07-02', '2023-07-03']
dt_index = pd.to_datetime(dates_list)
print(dt_index, type(dt_index))

# 处理异常数据
messy_dates = ['2023-07-01', '2023-07-02', 'invalid_date', '2023-07-04']
# ignore模式:保留原始输入
result_ignore = pd.to_datetime(messy_dates, errors='ignore')
print('ignore模式:', result_ignore)

# coerce模式:无效值转换为NaT
result_coerce = pd.to_datetime(messy_dates, errors='coerce')
print('coerce模式:', result_coerce)

二、时间戳索引(DatetimeIndex)

1. 创建时间序列

import numpy as np

# 直接创建DatetimeIndex
date_rng = pd.DatetimeIndex(['2023-01-01', '2023-01-02', '2023-01-03'])
print(date_rng, type(date_rng))
print(date_rng[0], type(date_rng[0]))

# 基于时间索引创建Series
time_series = pd.Series(np.random.randn(3), index=date_rng)
print(time_series)
print(time_series.index)

2. 生成连续时间范围

# 基本用法:指定起止时间和周期数
rng1 = pd.date_range(start='2023-01-01', periods=5, freq='D')
print('基础时间范围:', rng1)

# normalize参数:标准化到午夜
rng2 = pd.date_range(start='2023-01-01 15:30', periods=5, 
                     normalize=True, name='normalized')
print('标准化后:', rng2)

# closed参数控制区间闭合方式
print('默认闭合:', pd.date_range('2023-01-01', '2023-01-04'))
print('右开:', pd.date_range('2023-01-01', '2023-01-04', inclusive='left'))
print('左开:', pd.date_range('2023-01-01', '2023-01-04', inclusive='right'))

# 工作日频率
print('工作日范围:', pd.bdate_range('2023-01-01', '2023-01-07'))

3. 频率设置详解

# 基础频率
print('每日:', pd.date_range('2023-01-01', '2023-01-05', freq='D'))
print('每小时:', pd.date_range('2023-01-01 08:00', '2023-01-01 12:00', freq='H'))
print('每分钟:', pd.date_range('2023-01-01 08:00', '2023-01-01 08:05', freq='T'))

# 周频率:指定起始星期
print('每周一:', pd.date_range('2023-01-01', '2023-02-01', freq='W-MON'))

# 月频率:指定第几周的星期几
print('每月第二个周一:', pd.date_range('2023-01-01', '2023-05-01', freq='WOM-2MON'))

# 季度和年度频率
print('季度末:', pd.date_range('2023', '2024', freq='Q-DEC'))
print('年度末:', pd.date_range('2023', '2025', freq='A-DEC'))

# 复合频率
print('每3天:', pd.date_range('2023-01-01', '2023-01-15', freq='3D'))
print('每2小时30分:', pd.date_range('2023-01-01 08:00', '2023-01-01 15:00', freq='2h30min'))

4. 时间序列的位移操作

# 创建时间序列
ts = pd.Series(np.random.rand(4),
               index=pd.date_range('2023-01-01', '2023-01-04'))
print('原始数据:', ts, '\n')

# shift:数据位移(不影响索引)
print('后移2位:', ts.shift(2), '\n')
print('前移2位:', ts.shift(-2), '\n')

# 计算环比变化
change_ratio = ts / ts.shift(1) - 1
print('环比变化率:', change_ratio, '\n')

# 带freq参数的shift:索引位移
print('索引后移2天:', ts.shift(2, freq='D'), '\n')
print('索引后移30分钟:', ts.shift(2, freq='T'))

三、时间段(Period)处理

1. 创建时间段

# 创建月份周期
period = pd.Period('2023-01', freq='M')
print('月份周期:', period, type(period))

# 周期移动
print('下个月:', period + 1)
print('上个月:', period - 2)

# 年度周期
year_period = pd.Period('2023', freq='A-DEC')
print('年度周期:', year_period)
print('上一年:', year_period - 1)

2. 生成周期范围

# 创建PeriodIndex
period_range = pd.period_range('2023-01-01', '2023-06-01', freq='M')
print('周期索引:', period_range, type(period_range))
print('单个周期:', period_range[0], type(period_range[0]))

# 创建基于周期的序列
period_series = pd.Series(np.random.rand(len(period_range)), 
                          index=period_range)
print('周期序列:', period_series)

3. 周期频率转换

# 使用asfreq进行频率转换
p = pd.Period('2023', 'A-DEC')
print('原始:', p)
print('转为月起始:', p.asfreq('M', how='start'))
print('转为日结束:', p.asfreq('D', how='end'))

# 批量转换Series的索引
prng = pd.period_range('2023', '2024', freq='M')
ts1 = pd.Series(np.random.rand(len(prng)), index=prng)
ts2 = pd.Series(np.random.rand(len(prng)), 
                index=prng.asfreq('D', how='start'))
print('原始长度:', len(ts1))
print('转换后长度:', len(ts2))

4. 时间戳与周期互转

# to_period:时间戳转周期
rng = pd.date_range('2023-01-01', periods=6, freq='M')
ts_timestamp = pd.Series(np.random.rand(len(rng)), index=rng)
print('时间戳序列:', ts_timestamp.head())
print('转周期序列:', ts_timestamp.to_period().head())

# to_timestamp:周期转时间戳
prng = pd.period_range('2023', '2024', freq='M')
ts_period = pd.Series(np.random.rand(len(prng)), index=prng)
print('周期序列:', ts_period.head())
print('转时间戳序列:', ts_period.to_timestamp().head())

四、时间序列索引与切片

1. 基本索引

rng = pd.date_range('2023-01', '2023-03')
ts = pd.Series(np.random.rand(len(rng)), index=rng)

# 多种格式的索引
print('位置索引:', ts[0])
print('切片:', ts[:3])
print('日期索引:', ts['2023-01-15'])
print('紧凑格式:', ts['20230120'])
print('斜杠格式:', ts['1/25/2023'])
print('datetime对象:', ts[pd.Timestamp('2023-02-01')])

2. 高级切片

rng = pd.date_range('2023-01', '2023-03', freq='12H')
ts = pd.Series(np.random.rand(len(rng)), index=rng)

# 日期范围切片(包含端点)
print('日期范围:', ts['2023-01-05':'2023-01-10'])

# 月份切片
print('整月数据:', ts['2023-02'])

3. 处理重复索引

# 创建重复索引
dup_dates = pd.DatetimeIndex(['2023-01-01', '2023-01-02', '2023-01-03',
                              '2023-01-04', '2023-01-01', '2023-01-02'])
dup_ts = pd.Series(np.random.rand(6), index=dup_dates)
print('重复索引序列:', dup_ts)
print('是否唯一:', dup_ts.is_unique, dup_ts.index.is_unique)

# 重复索引返回多个值
print('重复日期查询:', dup_ts['2023-01-01'])
print('唯一日期查询:', dup_ts['2023-01-04'])

# 使用groupby处理重复
print('聚合处理:', dup_ts.groupby(level=0).mean())

五、重采样技术

1. 基础重采样

# 日频率转5天频率
rng = pd.date_range('2023-01-01', periods=12)
ts = pd.Series(np.arange(12), index=rng)

print('原始数据:', ts, '\n')

# 重采样构建器
resampler = ts.resample('5D')
print('重采样对象:', resampler, type(resampler))

# 各种聚合方法
print('求和:', ts.resample('5D').sum())
print('均值:', ts.resample('5D').mean())
print('最大值:', ts.resample('5D').max())
print('中位数:', ts.resample('5D').median())
print('首个值:', ts.resample('5D').first())
print('最后一个值:', ts.resample('5D').last())
print('OHLC:', ts.resample('5D').ohlc())

2. 降采样控制

rng = pd.date_range('2023-01-01', periods=12)
ts = pd.Series(np.arange(1, 13), index=rng)

# closed参数控制区间闭合
print('默认:', ts.resample('5D').sum())
print('左闭:', ts.resample('5D', closed='left').sum())
print('右闭:', ts.resample('5D', closed='right').sum())

# label参数控制索引标签
print('左标签:', ts.resample('5D', label='left').sum())
print('右标签:', ts.resample('5D', label='right').sum())

3. 升采样与插值

# 创建小时频率数据
rng = pd.date_range('2023-01-01 08:00', periods=5, freq='H')
df = pd.DataFrame(np.arange(15).reshape(5, 3),
                  index=rng,
                  columns=['x', 'y', 'z'])
print('原始数据:', df, '\n')

# 升采样到15分钟
print('asfreq(空值填充):', df.resample('15T').asfreq(), '\n')
print('向前填充:', df.resample('15T').ffill(), '\n')
print('向后填充:', df.resample('15T').bfill())

4. 周期重采样

prng = pd.period_range('2023', '2024', freq='M')
ts = pd.Series(np.arange(len(prng)), index=prng)
print('原始周期数据:', ts, '\n')

# 降采样:月转季度
print('降采样:', ts.resample('3M').sum(), '\n')

# 升采样:月转15天
print('升采样(向前填充):', ts.resample('15D').ffill())

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。