热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python——Pandas时间序列数据处理

介绍Pandas是非常著名的开源数据处理库,我们可以通过它完成对数据集进行快速读取、转换、过滤、分析等一系列操作。同样,Pandas已经被证明为是非常强大的用于处理时间序列数据的工

介绍

Pandas 是非常著名的开源数据处理库,我们可以通过它完成对数据集进行快速读取、转换、过滤、分析等一系列操作。同样,Pandas 已经被证明为是非常强大的用于处理时间序列数据的工具。本节将介绍所有 Pandas 在时间序列数据上的处理方法。

知识点

  • 创建时间对象
  • 时间索引对象
  • 时间算术方法

创建时间对象

在 Pandas 中关于时间序列的常见对象有 6 种,分别是 Timestamp(时间戳)、DatetimeIndex(时间戳索引)、Period(时间段)、PeriodIndex(时间段索引)、以时间为元素的 Series 和以及以时间索引的 DataFrame。本小节学习如何创建以上对象。

创建时间戳

Timestamp 时间戳表示时间轴上的某一点,以下不同代码都可以生成相同时间戳。

创建时间为 2018 年 10 月 1 日的时间戳。

import pandas as pd

pd.Timestamp(2018, 10, 1)

也可以使创建的时间精确到时分秒。

pd.Timestamp("2018-10-1 10:00:1")
from datetime import datetime

pd.Timestamp(datetime(2018, 10, 1))

创建时间段

Period 时间段表示时间轴上的某一区间,以下代码都可以生成相同时间段。

pd.Period('2018-10')

Period() 函数后面通常有两个参数,第二个 freq 参数决定时间段的分割长度。

创建频率为日的时间段。

pd.Period('2018-10', freq='D')

创建时间元素的 Series

Pandas 中常用 to_datetime() 函数可以创建以时间为元素的 Series。

创建一个 Series,以三个时间的字符串作为元素。

df = ['2018-08-01', '2018-09-01', '2018-10-01']
pd.to_datetime(df)

可以使用多种方法创建时间元素的 Series。

df = pd.Series(['Sep 30, 2018', '2018-10-1', None])
pd.to_datetime(df)
df = pd.DataFrame({'year': [2017, 2018],
                   'month': [9, 10],
                   'day': [30, 1],
                   'hour': [23, 0]})
pd.to_datetime(df)

创建时间索引

要生成带有时间戳的索引,可以使用 DatetimeIndex() 构造函数,并传入列表或 Series 对象:

dates = ['2018-08-01', '2018-09-01', '2018-10-01']
index = pd.DatetimeIndex(dates)
index

实际运用中我们经常需要大量的的时间戳的索引。可以使用 date_range()bdate_range() 来批量创建相同时间间隔的时间戳索引。

创建以 2018 年 9 月 30 日为开始的 250 条时间索引,相邻索引间隔时间长度为一个月。

index = pd.date_range('2018-9-30', periods=250, freq='M')
index

创建以 2018 年 10 月 1 日为开始的 111 条时间索引,相邻索引间隔时间长度为一个工作日。

index = pd.bdate_range('2018-10-1', periods=111)
index

date_range()bdate_range() 中可以巧妙使用 start,end, periods,freq 等参数的各种组合轻松批量创建时间索引。

在 2017 年 10 月 1 日到 2018 年 10 月 1 日间,每隔一周创建一条索引。

start = datetime(2017, 10, 1)
end = datetime(2018, 10, 1)
rng = pd.date_range(start, end, freq='W')
rng

从 2018 年 10 月 1 日向前每隔一个工作日创建一条索引,共 250 条。

pd.bdate_range(end=end, periods=250)

同理,时间段也能作为索引使用,需要用到 period_range()

从 2018 年 9 月 30 日向后创建 666 条索引,相邻索引间隔时间长度为一天。

pi = pd.period_range('2018-9-30', periods=666)
pi

创建以时间为索引的 Series 对象

以时间为索引的 Series 对象指的是在该 Series 中,元素的索引不再是 1、2、3、4、5……这样的序号,而是有序的日期和时间。

import numpy as np

dates = [pd.Timestamp('2018-08-01'), pd.Timestamp('2018-09-01'),
         pd.Timestamp('2018-10-01')]  # 创建三个时间元素。
ts = pd.Series(np.random.randn(3), dates)   # 创建索引值为随机数的 Series 对象。
ts

同样,时间段也能作为索引。

periods = [pd.Period('2018-08'), pd.Period('2018-09'), pd.Period('2018-10')]
ts = pd.Series(np.random.randn(3), periods)
ts

我们可以批量创建索引后再创建以时间为索引的 Series 对象。创建索引值为随机数的 Series 对象,长度与 rng 长度相同。

ts = pd.Series(np.random.randn(len(rng)), index=rng)
ts

时间段也能作为索引创建 DataFrame 对象。在 2017 年第一季度和 2018 年第四季度之间每隔一个季度创建一条索引。

prng = pd.period_range('2017Q1', '2018Q4', freq='Q-NOV')
# 行索引为时间段索引,列索引为 A。
ps = pd.DataFrame(np.random.rand(len(prng)), columns=[
                  'A'], index=prng)
ps

时间索引对象处理

以时间戳为索引的 Series、DataFrame 对象具有与普通列表近乎相同的操作,且更具智能化。

查找

简单查找。

ts

查找前 10 条索引记录。

ts[:10]

每隔 1 条记录查找 1 条索引记录。

ts[::2]

查找第 0、2、6 条索引记录。

ts[[0, 2, 6]]

基于时间索引的精确查找。查找索引为 2018 年 9 月 30 日的值。

ts["09/30/2018"]
ts[datetime(2018, 9, 30)]

基于索引的范围查找。查找索引时间在 2017 年内的所有记录。

ts["2017"]

查找索引时间在 2018 年 9 月内的所有记录。

ts["2018-9"]

以时间段为索引的 DataFrame 对象的查找规则与以时间戳的相同。

ps

2018 年的第一个季度规定为 2017 年的 12 月初到 2018 年的 2 月末。

查找 2017 年内的所有季度的记录。

ps["2017"]

查找 2017 年 12 月 31 日前的所有季度的记录。

ps[:datetime(2017, 12, 31)]

查找 2018 年 6 月内的所有季度的记录。

ps["2018-06"]

切片

使用 truncate() 切下 2017 年 11 月 26 日与 2018 年 4 月 29 日间的记录。

ts.truncate(before='11/26/2017', after='4/29/2018')

移动

将时间索引 Series 中的值向后和向前移动。其方法是 shift()

ts = ts[:5]  # 取前 5 条数据方便观察。
ts

将元素列向下移动一条。

ts.shift(1)

除了元素可以被移动,索引本身也能被移动,需要加上 freq 参数。将索引列向上移动一条:

ts.shift(1, freq='W')

重采样

重采样可以通俗得理解为改变时间索引的个数,通过增大或减小相邻索引的时间间隔以达到减小或增加索引数量的效果,在 Pandas 中使用 resample() 函数。

下采样:增大时间间隔,减少记录的数量。创建从 2018 年 10 月 1 日开始的日间隔索引的 Series 。

rng = pd.date_range('10/1/2018', periods=10, freq='D')
ts = pd.Series(np.random.randint(0, 50, len(rng)), index=rng)
ts

原先索引的日间隔被扩大为周间隔,并以周末为索引采样点,采样点的索引值为所有未被索引值的和。

ts.resample('W').sum()

同样也能使采样点的索引值为所有未被索引值的平均值。

ts.resample('W').mean()

使用 ohlc() 函数对所用未被采样值进行统计。

ts.resample('W').ohlc()

上采样:减小时间间隔频率,增加记录的数量。

原来间隔为日的索引列,间隔被缩小成 12 小时,增加采样点的值为空值。

ts.resample('12H').asfreq()

ffill() 函数可以将新增的索引值以相邻的前一条索引值进行填充。

ts.resample('12H').ffill()

时间的算术方法

常用时间的算术规则

下表是 Pandas 内建的一些时间类,常用于时间索引的位移。

技术图片

首先要导入 pandas.tseries.offsets 模块,Pandas 所有常用时间类都在该模块中。

d = pd.Timestamp(2018, 10, 1, 10, 1, 1)
d

使用 DateOffset() 实现时间戳位移。

向后移动一个月零两天。

from pandas.tseries.offsets import DateOffset

d + DateOffset(mOnths=1, days=2)

也可以用时间戳加减常用时间类以实现时间戳位移。向前移动 10 个工作日。

from pandas.tseries.offsets import BDay

d - 10 * BDay()

向后移动一个月末。

from pandas.tseries.offsets import BMonthEnd

d + BMonthEnd()

个性化定制日期。虽然日历规定年末是 12 月,加入参数后相当于人为规定 2 月是年末。

向后移动到上两个年末。

from pandas.tseries.offsets import YearEnd

d + YearEnd(mOnth=2)

向前移动到上一个周四。

from pandas.tseries.offsets import Week

d - Week(weekday=4)

可以使用 rollforward() 将指定时间向前或向后移动到一个制定常用时间类的时间戳上。将时间移动到下一个月末:

offset = BMonthEnd()
offset.rollforward(d)

将时间移动到上一个月末。

offset.rollback(d)

偏移也同样适用于时间索引

rng

所有的时间索引向后移动两日。

rng + DateOffset(days=2)

所有的时间索引向后移动两个工作日。

rng + 2*BDay()

所有的时间索引向后移动 15 分钟。

from pandas.tseries.offsets import Minute

rng + Minute(15)

下列是常用时间系列频率参数,上面小节经常出现,现在以一个表格作详细说明。

参数名 说明
B 工作日频率
C 定制工作日频率
D 日历日频率
W 每周频率
M 月结束频率
SM 半月结束频率(15 个月和月末)
BM 业务月末频率
CBM 定制业务月末频率
MS 月起始频率
sMs 半月起始频率(第 1 和 15)
BMS 业务月开始频率
CBMS 定制商业月份开始频率
Q 四分频结束频率
BQ 业务四分之一频率
QS 四分频启动频率
BQS 业务季开始频率
A 年结束频率
BA 业务年结束频率
AS 年起始频率
BAS 业务年开始频率
BH 工作时间频率
H 每小时频率
T, min 分钟频率
S 次频
L, ms 毫秒
U, uS 微秒
N 纳秒

使用常用频率参数组合创建时间索引。

创建 10 条以 2018 年 10 月 1 日为开始,间隔为 1 天 1 小时 1 分钟 10 微秒的时间索引。

pd.date_range("2018-10-1", periods=10, freq='1D1H1min10U')

以下频率参数可以指定后缀以达到改变默认间隔点的效果。

技术图片

创建 10 条以 2018 年 10 月 1 日为开始,间隔为每周三的时间索引。

pd.date_range("2018-10-1", periods=10, freq='W-WED')

在使用特定频率(MonthEnd,MonthBegin,WeekEnd 等)的参数时,如果起始时间是刚好在频率点上,使用 n 参数可以决定是否让该点参与计算。

n=1 时参与计算。

from pandas.tseries.offsets import MonthBegin

pd.Timestamp('2018-10-1') + MonthBegin(n=1)

n=0 时不参与计算。

pd.Timestamp('2018-10-1') + MonthBegin(n=0)

下采样聚合

下采样中的聚合是指下采样后,对未被采样到的点进行的一系列计算。

创建 100 个日历日为时间索引的 DataFrame,将其以月频率下采样。

df = pd.DataFrame(np.random.rand(100, 3),
                  index=pd.date_range('10/1/2018', freq='D', periods=100),
                  columns=['A', 'B', 'C'])
r = df.resample('M')
r

对未采样点求和,结果保存在采样点的值中。

r.sum()

在下采样后也能进行查找操作。选择 A、C 列后取均值计算。

r[['A', 'C']].mean()

使用 agg() 同时进行不同的计算。对采样结果进行取和与取均值计算。

r.agg([np.sum, np.mean])

选择 A 列,同时进行取和,取均值,取标准差计算。

r['A'].agg([np.sum, np.mean, np.std]

对 A 列求和与标准差,对 B 列求均值与标准差。

r.agg({'A': ['sum', 'std'], 'B': ['mean', 'std']})

总结

本章节介绍了 Pandas 对时间序列数据的基本处理操作。重点演示了时间的创建、时间索引对象的处理、时间的相关计算。当然,文中对这些方法的介绍依然还不够详细。如果你需要在实际工作中进行更复杂的时间数据处理,还需要深刻理解文中的基本演示,改编或组合出更高级的功能,这样才能发挥出 Pandas 的强大作用。

Python——Pandas 时间序列数据处理


推荐阅读
  • 本文深入解析了Java面向对象编程的核心概念及其应用,重点探讨了面向对象的三大特性:封装、继承和多态。封装确保了数据的安全性和代码的可维护性;继承支持代码的重用和扩展;多态则增强了程序的灵活性和可扩展性。通过具体示例,文章详细阐述了这些特性在实际开发中的应用和优势。 ... [详细]
  • 资源管理器的基础架构包括三个核心组件:1)资源池,用于将CPU和内存等资源分配给不同的容器;2)负载组,负责承载任务并将其分配到相应的资源池;3)分类函数,用于将不同的会话映射到合适的负载组。该系统提供了两种主要的资源管理策略。 ... [详细]
  • 在探讨Hibernate框架的高级特性时,缓存机制和懒加载策略是提升数据操作效率的关键要素。缓存策略能够显著减少数据库访问次数,从而提高应用性能,特别是在处理频繁访问的数据时。Hibernate提供了多层次的缓存支持,包括一级缓存和二级缓存,以满足不同场景下的需求。懒加载策略则通过按需加载关联对象,进一步优化了资源利用和响应时间。本文将深入分析这些机制的实现原理及其最佳实践。 ... [详细]
  • 本文详细介绍了使用 Python 进行 MySQL 和 Redis 数据库操作的实战技巧。首先,针对 MySQL 数据库,通过 `pymysql` 模块展示了如何连接和操作数据库,包括建立连接、执行查询和更新等常见操作。接着,文章深入探讨了 Redis 的基本命令和高级功能,如键值存储、列表操作和事务处理。此外,还提供了多个实际案例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • DRF框架中Serializer反序列化验证机制详解:深入探讨Validators的应用与优化
    在DRF框架的反序列化验证机制中,除了基本的字段类型和长度校验外,还常常需要进行更为复杂的条件限制校验。通过引入`validators`模块,可以实现自定义校验逻辑,如唯一字段校验等。本文将详细探讨`validators`的使用方法及其优化策略,帮助开发者更好地理解和应用这一重要功能。 ... [详细]
  • 本文探讨了如何有效地构建和优化微信公众平台账号,涵盖了用户信息管理、内容创作与发布、互动策略及数据分析等方面。通过合理设置用户信息字段,如用户名、昵称、密码、真实姓名和性别等,确保账号的安全性和用户体验。同时,文章还介绍了如何利用微信公众平台的各项功能,提升用户参与度和品牌影响力。 ... [详细]
  • 如何高效利用Hackbar插件提升网页调试效率
    通过合理利用Hackbar插件,可以显著提升网页调试的效率。本文介绍了如何获取并使用未包含收费功能的2.1.3版本,以确保在不升级到最新2.2.2版本的情况下,依然能够高效进行网页调试。此外,文章还提供了详细的使用技巧和常见问题解决方案,帮助开发者更好地掌握这一工具。 ... [详细]
  • 并发编程入门:初探多任务处理技术
    并发编程入门:探索多任务处理技术并发编程是指在单个处理器上高效地管理多个任务的执行过程。其核心在于通过合理分配和协调任务,提高系统的整体性能。主要应用场景包括:1) 将复杂任务分解为多个子任务,并分配给不同的线程,实现并行处理;2) 通过同步机制确保线程间协调一致,避免资源竞争和数据不一致问题。此外,理解并发编程还涉及锁机制、线程池和异步编程等关键技术。 ... [详细]
  • 本指南旨在帮助Swoole初学者快速掌握异步并发编程的基本概念和实践方法。通过实例演示,我们将使用Swoole PHP扩展构建一个简单的客户端与服务器模型,并实现基本的通信功能。首先,我们将从客户端的实现入手(文件名为:client.php)。 ... [详细]
  • 在Ubuntu系统中配置Python环境变量是确保项目顺利运行的关键步骤。本文介绍了如何将Windows上的Django项目迁移到Ubuntu,并解决因虚拟环境导致的模块缺失问题。通过详细的操作指南,帮助读者正确配置虚拟环境,确保所有第三方库都能被正确识别和使用。此外,还提供了一些实用的技巧,如如何检查环境变量配置是否正确,以及如何在多个虚拟环境之间切换。 ... [详细]
  • 在 POJ1651 的乘法谜题挑战中,如果选手按相反顺序选择卡片,即先选 50,再选 20,最后选 1,则最终得分会有所不同。题目要求输入的第一行包含... 改写后的摘要:在 POJ1651 的乘法谜题挑战中,如果选手按照逆序选取卡片,例如依次选择 50、20 和 1,最终的得分将发生变化。题目首先要求输入的第一行包括... ... [详细]
  • 在本节课程中,我们将深入探讨 JSP 编程中的实际案例,通过具体代码示例 `code316.java` 来解析数据库连接的实现。该示例展示了如何使用 Java 的 JDBC API 进行数据库操作,包括加载数据库驱动、建立连接等关键步骤。通过本课程的学习,读者将能够更好地理解和应用 JSP 中的数据库连接技术。 ... [详细]
  • 每年,意甲、德甲、英超和西甲等各大足球联赛的赛程表都是球迷们关注的焦点。本文通过 Python 编程实现了一种生成赛程表的方法,该方法基于蛇形环算法。具体而言,将所有球队排列成两列的环形结构,左侧球队对阵右侧球队,首支队伍固定不动,其余队伍按顺时针方向循环移动,从而确保每场比赛不重复。此算法不仅高效,而且易于实现,为赛程安排提供了可靠的解决方案。 ... [详细]
  • Docker入门指南:初探容器化技术
    Docker入门指南:初探容器化技术摘要:Docker 是一个使用 Go 语言开发的开源容器平台,旨在实现应用程序的构建、分发和运行的标准化。通过将应用及其依赖打包成轻量级的容器,Docker 能够确保应用在任何环境中都能一致地运行,从而提高开发和部署的效率。本文将详细介绍 Docker 的基本概念、核心功能以及如何快速上手使用这一强大的容器化工具。 ... [详细]
  • 使用for循环构建标准等腰三角形
    通过使用 `for` 循环,可以构建一个标准的等腰三角形。具体来说,每层的星号数量为 `2*i-1`,而空格的数量则为 `(n-i)*2`,其中 `n` 是总层数,`i` 是当前层的索引。通过合理地控制星号和空格的数量,可以确保生成的三角形在视觉上是标准且对称的。例如,对于一个 4 层的等腰三角形,第一层有 1 个星号和 6 个空格,第二层有 3 个星号和 4 个空格,依此类推。这种算法不仅简单高效,而且易于实现。 ... [详细]
author-avatar
嘻嘻520000000
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有