Pandas 系列文章:
专栏:
【NumPy 专栏 】【Pandas 专栏 】【Matplotlib 专栏 】
推荐学习资料与网站:
【NumPy 中文网 】【Pandas 中文网 】【Matplotlib 中文网 】【NumPy、Matplotlib、Pandas 速查表 】
1 2 3 4 5 这里是一段防爬虫文本,请读者忽略。 本文原创首发于 CSDN,作者 TRHX。 博客首页:https://itrhx.blog.csdn.net/ 本文链接:https://itrhx.blog.csdn.net/article/details/106947061 未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!
【01x00】时间序列 官网对于时间序列的介绍:https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html
时间序列(time series)是一种重要的结构化数据形式,应用于多个领域,包括金融学、经济学、生态学、神经科学、物理学等。在多个时间点观察或测量到的任何事物都可以形成一段时间序列。很多时间序列是固定频率的,也就是说,数据点是根据某种规律定期出现的(比如每15秒、每5分钟、每月出现一次)。时间序列也可以是不定期的,没有固定的时间单位或单位之间的偏移量。时间序列数据的意义取决于具体的应用场景,主要有以下几种:
时间戳(timestamp),表示某个具体的时间点,例如 2020-6-24 15:30;
固定周期(period),表示某个时间周期,例如 2020-01;
时间间隔(timedelta),持续时间,即两个日期或时间之间的差异。
针对时间戳数据,Pandas 提供了 Timestamp 类型。它本质上是 Python 的原生 datetime 类型的替代品,但是在性能更好的 numpy.datetime64 类型的基础上创建。对应的索引数据结构是 DatetimeIndex。
针对时间周期数据,Pandas 提供了 Period 类型。这是利用 numpy.datetime64 类型将固定频率的时间间隔进行编码。对应的索引数据结构是 PeriodIndex。
针对时间增量或持续时间,Pandas 提供了 Timedelta 类型。Timedelta 是一种代替 Python 原生datetime.timedelta 类型的高性能数据结构,同样是基于 numpy.timedelta64 类型。对应的索引数据结构是 TimedeltaIndex。
【02x00】Timestamp 时间戳 【02x01】pandas.Timestamp 在 pandas 中,pandas.Timestamp
方法用来代替 Python 中的 datetime.datetime
方法。
Timestamp 与 Python 的 Datetime 等效,在大多数情况下都可以互换。 此类型用于组成 DatetimeIndex 以及 Pandas 中其他面向时间序列的数据结构。
官方文档:https://pandas.pydata.org/docs/reference/api/pandas.Timestamp.html
基本语法:
1 2 3 4 5 class pandas .Timestamp (ts_input=<object object>, freq=None, tz=None, unit=None, year=None, month=None, day=None, hour=None, minute=None, second=None, microsecond=None, nanosecond=None, tzinfo=None)
常用参数:
参数
描述
ts_input
要转换为时间戳的对象,可以是 datetime-like,str,int,float 类型
freq
时间戳将具有的偏移量,可以是 str,日期偏移量类型,取值参见【02x02】freq 频率部分取值
tz
时间戳将具有的时区
unit
如果 ts_input 是整数或浮点数,该参数用于设置其单位(D、s、ms、us、ns)
简单示例:
1 2 3 >>> import pandas as pd>>> pd.Timestamp('2017-01-01T12' )Timestamp('2017-01-01 12:00:00' )
设置 unit='s'
,即待转换对象单位为秒:
1 2 3 >>> import pandas as pd>>> pd.Timestamp(1513393355.5 , unit='s' )Timestamp('2017-12-16 03:02:35.500000' )
使用 tz
参数设置时区:
1 2 3 >>> import pandas as pd>>> pd.Timestamp(1513393355 , unit='s' , tz='US/Pacific' )Timestamp('2017-12-15 19:02:35-0800' , tz='US/Pacific' )
单独设置年月日:
1 2 3 >>> import pandas as pd>>> pd.Timestamp(year=2020 , month=6 , day=24 , hour=12 )Timestamp('2020-06-24 12:00:00' )
【02x02】freq 频率部分取值 完整取值参见官方文档:https://pandas.pydata.org/docs/user_guide/timeseries.html#timeseries-offset-aliases
参数
类型
描述
D
Day
每日历日
B
BusinessDay
每工作日
H
Hour
每小时
T 或 min
Minute
每分
S
Second
每秒
L 或 ms
Milli
每毫秒(即每千分之一秒)
U
Micro
每微秒(即每百万分之一秒)
M
MonthEnd
每月最后一个日历日
BM
BusinessMonthEnd
每月最后一个工作日
MS
MonthBegin
每月第一个日历日
BMS
BusinessMonthBegin
每月第一个工作日
W-MON、W-TUE…
Week
从指定的星期几(MON、TUE、 WED、THU、FR、SAT、SUN)开始算起,每周
WoM-1MON、WOM-2MON…
WeekOfMonth
产生每月第一、第二、第三或第四周的星期几。例如,WoM-3FRI 表示每月第3个星期五
Q-JAN、Q-FEB…
QuarterEnd
对于以指定月份(JAN、FEB、MAR、APR、MAY、JUN、JUL、AUG、SEP、OCT、NOV、DEC)结束的年度,每季度最后一月的最后个日历日
BQ-JAN、BQ-FEB…
BusinessQuarterEnd
对于以指定月份结束的年度,每季度最后一月的最后一个工作日
QS-JAN、QS-FEB…
QuarterBegin
对于以指定月份结束的年度,每季度最后一月的第一个日历日
BQS-JAN、 BQS-FEB…
BusinessQuarterBegin
对于以指定月份结束的年度,每季度最后一月的第一个工作日
A-JAN、A-FEB…
YearEnd
每年指定月份(JAN、FEB、MAR、APR、MAY、JUN、JUL、AUG、SEP、 OCT、NOV、DEC)的最后一个日历日
BA-JAN、BA-FEB…
BusinessYearEnd
每年指定月份的最后一个工作日
AS-JAN、AS-FEB…
YearBegin
每年指定月份的第一个历日日
BAS-JAN、BAS-FEB…
BusinessYearBegin
每年指定月份的第一个工作日
【02x03】to_datetime 在 Python 中,datetime 库提供了日期和时间处理方法,利用 str
或 strftime
方法可以将 datetime 对象转化成字符串,具体用法可参见【Python 标准库学习】日期和时间处理库 — datetime 。
1 2 3 4 5 6 7 8 9 10 >>> from datetime import datetime>>> stamp = datetime(2020 , 6 , 24 )>>> stampdatetime.datetime(2020 , 6 , 24 , 0 , 0 ) >>> >>> str(stamp)'2020-06-24 00:00:00' >>> >>> stamp.strftime('%Y-%m-%d' )'2020-06-24'
在 pandas 中 to_datetime 方法可以将字符串解析成多种不同的 Timestamp(时间戳) 对象:
1 2 3 4 5 6 7 >>> import pandas as pd>>> datestrs = '2011-07-06 12:00:00' >>> type(datestrs)<class 'str '> >>> >>> pd .to_datetime (datestrs) Timestamp ('2011-07-06 12:00:00' )
基本语法:
1 2 3 4 pandas.to_datetime(arg, errors='raise' , dayfirst=False , yearfirst=False , utc=None , format=None , exact=True , unit=None , infer_datetime_format=False , origin='unix' , cache=True )
官方文档:https://pandas.pydata.org/docs/reference/api/pandas.to_datetime.html
常用参数:
参数
描述
arg
要转换为日期时间的对象,可以接受 int, float, str, datetime, list, tuple, 1-d array, Series DataFrame/dict-like 类型
errors
如果字符串不满足时间戳的形式,是否会发生异常ignore
:不引发异常,返回原始输入;raise
:无效解析将引发异常(默认);coerce
:无效解析将被设置为NaT
dayfirst
bool 类型,默认 False,如果 arg 是 str 或列表,是否首先解析为日期 例如 dayfirst 为 True,10/11/12
被解析为 2012-11-10
,为 False 则解析为 2012-10-11
yearfirst
bool 类型,默认 False,如果 arg 是 str 或列表,是否首先解析为年份 例如 dayfirst 为 True,10/11/12
被解析为 2010-11-12
,为 False 则解析为 2012-10-11
如果 dayfirst 和 yearfirst 都为 True,则优先 yearfirst
utc
bool 类型,是否转换为协调世界时,默认 None
format
格式化时间,如 21/2/20 16:10
使用 %d/%m/%y %H:%M
会被解析为 2020-02-21 16:10:00
符号含义常见文章:【Python 标准库学习】日期和时间处理库 — datetime 或者官方文档
exact
如果为 True,则需要精确的格式匹配。如果为 False,则允许格式与目标字符串中的任何位置匹配
unit
如果 arg 是整数或浮点数,该参数用于设置其单位(D、s、ms、us、ns)
简单应用:
1 2 3 4 5 6 7 8 9 10 11 >>> import pandas as pd>>> obj = pd.DataFrame({'year' : [2015 , 2016 ], 'month' : [2 , 3 ], 'day' : [4 , 5 ]})>>> obj year month day 0 2015 2 4 1 2016 3 5 >>> >>> pd.to_datetime(obj)0 2015 -02 -04 1 2016 -03 -05 dtype: datetime64[ns]
设置 format
和 errors
参数:
1 2 3 4 5 6 7 8 9 10 11 >>> import pandas as pd>>> pd.to_datetime('13000101' , format='%Y%m%d' , errors='ignore' )datetime.datetime(1300 , 1 , 1 , 0 , 0 ) >>> >>> pd.to_datetime('13000101' , format='%Y%m%d' , errors='coerce' )NaT >>> >>> pd.to_datetime('13000101' , format='%Y%m%d' , errors='raise' )Traceback (most recent call last): ... pandas._libs.tslibs.np_datetime.OutOfBoundsDatetime: Out of bounds nanosecond timestamp: 1300 -01 -01 00 :00 :00
设置 unit
参数:
1 2 3 4 5 6 >>> import pandas as pd>>> pd.to_datetime(1490195805 , unit='s' )Timestamp('2017-03-22 15:16:45' ) >>> >>> pd.to_datetime(1490195805433502912 , unit='ns' )Timestamp('2017-03-22 15:16:45.433502912' )
【02x04】date_range pandas.date_range
方法可用于根据指定的频率生成指定长度的 DatetimeIndex。
基本语法:
1 2 3 pandas.date_range(start=None , end=None , periods=None , freq=None , tz=None , normalize=False , name=None , closed=None , **kwargs) → pandas.core.indexes.datetimes.DatetimeIndex
官方文档:https://pandas.pydata.org/docs/reference/api/pandas.date_range.html
参数
描述
start
开始日期
end
结束日期
periods
int 类型,要生成的时段数(天)
freq
频率字符串,即按照某种特定的频率来生成日期,取值参见【02x02】freq 频率部分取值
tz
设置时区,例如 “Asia/Hong_Kong”
normalize
bool 类型,默认 False,是否在生成日期之前对其进行规范化(仅保留年月日)
name
结果 DatetimeIndex 的名称
closed
None
:默认值,同时保留开始日期和结束日期'left'
:保留开始日期,不保留结束日期'right'
:保留结束日期,不保留开始日期
简单示例:
1 2 3 4 5 >>> import pandas as pd>>> pd.date_range(start='1/1/2018' , end='1/08/2018' )DatetimeIndex(['2018-01-01' , '2018-01-02' , '2018-01-03' , '2018-01-04' , '2018-01-05' , '2018-01-06' , '2018-01-07' , '2018-01-08' ], dtype='datetime64[ns]' , freq='D' )
指定 periods
参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 >>> import pandas as pd>>> pd.date_range(start='2012-04-01' , periods=20 )DatetimeIndex(['2012-04-01' , '2012-04-02' , '2012-04-03' , '2012-04-04' , '2012-04-05' , '2012-04-06' , '2012-04-07' , '2012-04-08' , '2012-04-09' , '2012-04-10' , '2012-04-11' , '2012-04-12' , '2012-04-13' , '2012-04-14' , '2012-04-15' , '2012-04-16' , '2012-04-17' , '2012-04-18' , '2012-04-19' , '2012-04-20' ], dtype='datetime64[ns]' , freq='D' ) >>> >>> pd.date_range(end='2012-06-01' , periods=20 )DatetimeIndex(['2012-05-13' , '2012-05-14' , '2012-05-15' , '2012-05-16' , '2012-05-17' , '2012-05-18' , '2012-05-19' , '2012-05-20' , '2012-05-21' , '2012-05-22' , '2012-05-23' , '2012-05-24' , '2012-05-25' , '2012-05-26' , '2012-05-27' , '2012-05-28' , '2012-05-29' , '2012-05-30' , '2012-05-31' , '2012-06-01' ], dtype='datetime64[ns]' , freq='D' ) >>> >>> pd.date_range(start='2018-04-24' , end='2018-04-27' , periods=3 )DatetimeIndex(['2018-04-24 00:00:00' , '2018-04-25 12:00:00' , '2018-04-27 00:00:00' ], dtype='datetime64[ns]' , freq=None ) >>> >>> pd.date_range(start='2018-04-24' , end='2018-04-28' , periods=3 )DatetimeIndex(['2018-04-24' , '2018-04-26' , '2018-04-28' ], dtype='datetime64[ns]' , freq=None )
指定 freq='M'
会按照每月最后一个日历日的频率生成日期,指定 freq='3M'
会每隔3个月按照每月最后一个日历日的频率生成日期:
1 2 3 4 5 6 7 8 9 10 11 >>> import pandas as pd>>> pd.date_range(start='1/1/2018' , periods=5 , freq='M' )DatetimeIndex(['2018-01-31' , '2018-02-28' , '2018-03-31' , '2018-04-30' , '2018-05-31' ], dtype='datetime64[ns]' , freq='M' ) >>> >>> pd.date_range(start='1/1/2018' , periods=5 , freq='3M' )DatetimeIndex(['2018-01-31' , '2018-04-30' , '2018-07-31' , '2018-10-31' , '2019-01-31' ], dtype='datetime64[ns]' , freq='3M' ) >>>
使用 tz
参数设置时区:
1 2 3 4 5 6 7 8 9 10 11 12 >>> import pandas as pd>>> pd.date_range(start='1/1/2018' , periods=5 , tz='Asia/Tokyo' )DatetimeIndex(['2018-01-01 00:00:00+09:00' , '2018-01-02 00:00:00+09:00' , '2018-01-03 00:00:00+09:00' , '2018-01-04 00:00:00+09:00' , '2018-01-05 00:00:00+09:00' ], dtype='datetime64[ns, Asia/Tokyo]' , freq='D' ) >>> >>> pd.date_range(start='6/24/2020' , periods=5 , tz='Asia/Hong_Kong' )DatetimeIndex(['2020-06-24 00:00:00+08:00' , '2020-06-25 00:00:00+08:00' , '2020-06-26 00:00:00+08:00' , '2020-06-27 00:00:00+08:00' , '2020-06-28 00:00:00+08:00' ], dtype='datetime64[ns, Asia/Hong_Kong]' , freq='D' )
设置 normalize
参数,在生成时间戳之前对其进行格式化操作:
1 2 3 4 5 >>> import pandas as pd>>> pd.date_range('2020-06-24 12:56:31' , periods=5 , normalize=True )DatetimeIndex(['2020-06-24' , '2020-06-25' , '2020-06-26' , '2020-06-27' , '2020-06-28' ], dtype='datetime64[ns]' , freq='D' )
设置 closed
参数:
1 2 3 4 5 6 7 8 9 10 11 >>> import pandas as pd>>> pd.date_range(start='2020-06-20' , end='2020-06-24' , closed=None )DatetimeIndex(['2020-06-20' , '2020-06-21' , '2020-06-22' , '2020-06-23' , '2020-06-24' ], dtype='datetime64[ns]' , freq='D' ) >>> >>> pd.date_range(start='2020-06-20' , end='2020-06-24' , closed='left' )DatetimeIndex(['2020-06-20' , '2020-06-21' , '2020-06-22' , '2020-06-23' ], dtype='datetime64[ns]' , freq='D' ) >>> >>> pd.date_range(start='2020-06-20' , end='2020-06-24' , closed='right' )DatetimeIndex(['2020-06-21' , '2020-06-22' , '2020-06-23' , '2020-06-24' ], dtype='datetime64[ns]' , freq='D' )
【02x05】索引与切片 Pandas 最基本的时间序列类型就是以时间戳(通常以 Python 字符串或 datatime 对象表示)为索引的Series,这些 datetime 对象实际上是被放在 DatetimeIndex 中的,可以使用类似 pandas.Series 对象的切片方法对其进行索引:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 >>> import pandas as pd>>> import numpy as np>>> dates = [datetime(2011 , 1 , 2 ), datetime(2011 , 1 , 5 ), datetime(2011 , 1 , 7 ), datetime(2011 , 1 , 8 ), datetime(2011 , 1 , 10 ), datetime(2011 , 1 , 12 )] >>> obj = pd.Series(np.random.randn(6 ), index=dates)>>> >>> obj2011 -01 -02 -0.407110 2011 -01 -05 -0.186661 2011 -01 -07 -0.731080 2011 -01 -08 0.860970 2011 -01 -10 1.929973 2011 -01 -12 -0.168599 dtype: float64 >>> >>> obj.indexDatetimeIndex(['2011-01-02' , '2011-01-05' , '2011-01-07' , '2011-01-08' , '2011-01-10' , '2011-01-12' ], dtype='datetime64[ns]' , freq=None ) >>> >>> obj.index[0 ]Timestamp('2011-01-02 00:00:00' ) >>> >>> obj.index[0 :3 ]DatetimeIndex(['2011-01-02' , '2011-01-05' , '2011-01-07' ], dtype='datetime64[ns]' , freq=None )
另外还可以传入一个可以被解释为日期的字符串,或者只需传入“年”或“年月”即可轻松选取数据的切片:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 >>> import pandas as pd>>> import numpy as np>>> obj = pd.Series(np.random.randn(1000 ), index=pd.date_range('1/1/2000' , periods=1000 ))>>> obj2000 -01 -01 -1.142284 2000 -01 -02 1.198785 2000 -01 -03 2.466909 2000 -01 -04 -0.086728 2000 -01 -05 -0.978437 ... 2002 -09 -22 -0.252240 2002 -09 -23 0.148561 2002 -09 -24 -1.330409 2002 -09 -25 -0.673471 2002 -09 -26 -0.253271 Freq: D, Length: 1000 , dtype: float64 >>> >>> obj['26/9/2002' ]-0.25327100684233356 >>> >>> obj['2002' ]2002 -01 -01 1.058715 2002 -01 -02 0.900859 2002 -01 -03 1.993508 2002 -01 -04 -0.103211 2002 -01 -05 -0.950090 ... 2002 -09 -22 -0.252240 2002 -09 -23 0.148561 2002 -09 -24 -1.330409 2002 -09 -25 -0.673471 2002 -09 -26 -0.253271 Freq: D, Length: 269 , dtype: float64 >>> >>> obj['2002-09' ]2002 -09 -01 -0.995528 2002 -09 -02 0.501528 2002 -09 -03 -0.486753 2002 -09 -04 -1.083906 2002 -09 -05 1.458975 2002 -09 -06 -1.331685 2002 -09 -07 0.195338 2002 -09 -08 -0.429613 2002 -09 -09 1.125823 2002 -09 -10 1.607051 2002 -09 -11 0.530387 2002 -09 -12 -0.015938 2002 -09 -13 1.781043 2002 -09 -14 -0.277123 2002 -09 -15 0.344569 2002 -09 -16 -1.010810 2002 -09 -17 0.463001 2002 -09 -18 1.883636 2002 -09 -19 0.274520 2002 -09 -20 0.624184 2002 -09 -21 -1.203057 2002 -09 -22 -0.252240 2002 -09 -23 0.148561 2002 -09 -24 -1.330409 2002 -09 -25 -0.673471 2002 -09 -26 -0.253271 Freq: D, dtype: float64 >>> >>> obj['20/9/2002' :'26/9/2002' ]2002 -09 -20 0.624184 2002 -09 -21 -1.203057 2002 -09 -22 -0.252240 2002 -09 -23 0.148561 2002 -09 -24 -1.330409 2002 -09 -25 -0.673471 2002 -09 -26 -0.253271 Freq: D, dtype: float64
【02x06】移动数据与数据偏移 移动(shifting)指的是沿着时间轴将数据前移或后移。Series 和 DataFrame 都有一个 shift 方法用于执行单纯的前移或后移操作,保持索引不变:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 >>> import pandas as pd>>> import numpy as np>>> obj = pd.Series(np.random.randn(4 ), index=pd.date_range('1/1/2000' , periods=4 , freq='M' )) >>> obj2000 -01 -31 -0.100217 2000 -02 -29 1.177834 2000 -03 -31 -0.644353 2000 -04 -30 -1.954679 Freq: M, dtype: float64 >>> >>> obj.shift(2 )2000 -01 -31 NaN2000 -02 -29 NaN2000 -03 -31 -0.100217 2000 -04 -30 1.177834 Freq: M, dtype: float64 >>> >>> obj.shift(-2 )2000 -01 -31 -0.644353 2000 -02 -29 -1.954679 2000 -03 -31 NaN2000 -04 -30 NaNFreq: M, dtype: float64
因为简单的移位操作不会修改索引,所以部分数据会被丢弃并引入 NaN(缺失值)。因此,如果频率已知,则可以将其传给 shift 以便实现对时间戳进行位移而不是对数据进行简单位移:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 >>> import pandas as pd>>> import numpy as np>>> obj = pd.Series(np.random.randn(4 ), index=pd.date_range('1/1/2000' , periods=4 , freq='M' )) >>> obj2000 -01 -31 -0.100217 2000 -02 -29 1.177834 2000 -03 -31 -0.644353 2000 -04 -30 -1.954679 Freq: M, dtype: float64 >>> >>> obj.shift(2 , freq='M' )2000 -03 -31 -0.100217 2000 -04 -30 1.177834 2000 -05 -31 -0.644353 2000 -06 -30 -1.954679 Freq: M, dtype: float64
Pandas 中的频率是由一个基础频率(base frequency)和一个乘数组成的。基础频率通常以一个字符串别名表示,比如 "M"
表示每月,"H"
表示每小时。对于每个基础频率,都有一个被称为日期偏移量(date offset)的对象与之对应。例如,按小时计算的频率可以用 Hour
类表示:
1 2 3 4 5 6 7 8 >>> from pandas.tseries.offsets import Hour, Minute>>> hour = Hour()>>> hour<Hour> >>> >>> four_hours = Hour(4 )>>> four_hours<4 * Hours>
一般来说,无需明确创建这样的对象,只需使用诸如 "H"
或 "4H"
这样的字符串别名即可。在基础频率前面放上一个整数即可创建倍数:
1 2 3 4 5 6 7 8 9 10 11 12 >>> import pandas as pd>>> pd.date_range('2000-01-01' , '2000-01-03 23:59' , freq='4h' )DatetimeIndex(['2000-01-01 00:00:00' , '2000-01-01 04:00:00' , '2000-01-01 08:00:00' , '2000-01-01 12:00:00' , '2000-01-01 16:00:00' , '2000-01-01 20:00:00' , '2000-01-02 00:00:00' , '2000-01-02 04:00:00' , '2000-01-02 08:00:00' , '2000-01-02 12:00:00' , '2000-01-02 16:00:00' , '2000-01-02 20:00:00' , '2000-01-03 00:00:00' , '2000-01-03 04:00:00' , '2000-01-03 08:00:00' , '2000-01-03 12:00:00' , '2000-01-03 16:00:00' , '2000-01-03 20:00:00' ], dtype='datetime64[ns]' , freq='4H' )
大部分偏移量对象都可通过加法进行连接:
1 2 3 >>> from pandas.tseries.offsets import Hour, Minute>>> Hour(2 ) + Minute(30 )<150 * Minutes>
对于 freq
参数也可以传入频率字符串(如 "2h30min"
),这种字符串可以被高效地解析为等效的表达式:
1 2 3 4 5 6 7 8 >>> import pandas as pd>>> pd.date_range('2000-01-01' , periods=10 , freq='1h30min' )DatetimeIndex(['2000-01-01 00:00:00' , '2000-01-01 01:30:00' , '2000-01-01 03:00:00' , '2000-01-01 04:30:00' , '2000-01-01 06:00:00' , '2000-01-01 07:30:00' , '2000-01-01 09:00:00' , '2000-01-01 10:30:00' , '2000-01-01 12:00:00' , '2000-01-01 13:30:00' ], dtype='datetime64[ns]' , freq='90T' )
这种偏移量还可以用在 datetime 或 Timestamp 对象上:
1 2 3 4 >>> from pandas.tseries.offsets import Day, MonthEnd>>> now = datetime(2011 , 11 , 17 )>>> now + 3 * Day()Timestamp('2011-11-20 00:00:00' )
如果加的是锚点偏移量,比如 MonthEnd,第一次增量会将原日期向前滚动到符合频率规则的下一个日期:
1 2 3 4 5 6 >>> from pandas.tseries.offsets import Day, MonthEnd>>> now = datetime(2011 , 11 , 17 )>>> now + MonthEnd()Timestamp('2011-11-30 00:00:00' ) >>> now + MonthEnd(2 )Timestamp('2011-12-31 00:00:00' )
通过锚点偏移量的 rollforward 和 rollback 方法,可明确地将日期向前或向后滚动:
1 2 3 4 5 6 7 >>> from pandas.tseries.offsets import Day, MonthEnd>>> now = datetime(2011 , 11 , 17 )>>> offset = MonthEnd()>>> offset.rollforward(now)Timestamp('2011-11-30 00:00:00' ) >>> offset.rollback(now)Timestamp('2011-10-31 00:00:00' )
与 groupby
方法结合使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 >>> import pandas as pd>>> import numpy as np>>> from pandas.tseries.offsets import Day, MonthEnd>>> obj = pd.Series(np.random.randn(20 ), index=pd.date_range('1/15/2000' , periods=20 , freq='4d' )) >>> obj2000 -01 -15 -0.591729 2000 -01 -19 -0.775844 2000 -01 -23 -0.745603 2000 -01 -27 -0.076439 2000 -01 -31 1.796417 2000 -02 -04 -0.500349 2000 -02 -08 0.515851 2000 -02 -12 -0.344171 2000 -02 -16 0.419657 2000 -02 -20 0.307288 2000 -02 -24 0.115113 2000 -02 -28 -0.362585 2000 -03 -03 1.074892 2000 -03 -07 1.111366 2000 -03 -11 0.949910 2000 -03 -15 -1.535727 2000 -03 -19 0.545944 2000 -03 -23 -0.810139 2000 -03 -27 -1.260627 2000 -03 -31 -0.128403 Freq: 4 D, dtype: float64 >>> >>> offset = MonthEnd()>>> obj.groupby(offset.rollforward).mean()2000 -01 -31 -0.078640 2000 -02 -29 0.021543 2000 -03 -31 -0.006598 dtype: float64
【02x07】时区处理 在 Python 中,时区信息来自第三方库 pytz,使用 pytz.common_timezones
方法可以查看所有的时区名称,使用 pytz.timezone
方法从 pytz 中获取时区对象:
1 2 3 4 5 6 7 >>> import pytz>>> pytz.common_timezones['Africa/Abidjan' , 'Africa/Accra' , 'Africa/Addis_Ababa' , ..., 'UTC' ] >>> >>> tz = pytz.timezone('Asia/Shanghai' )>>> tz<DstTzInfo 'Asia/Shanghai' LMT+8 :06 :00 STD>
在 date_range
方法中,tz
参数用于指定时区,默认为 None,可以使用 tz_localize
方法将其进行本地化时区转换,如下示例中,将无时区转本地化 UTC 时区:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 >>> import pandas as pd>>> import numpy as np>>> rng = pd.date_range('3/9/2012 9:30' , periods=6 , freq='D' )>>> ts = pd.Series(np.random.randn(len(rng)), index=rng)>>> ts2012 -03 -09 09 :30 :00 -1.527913 2012 -03 -10 09 :30 :00 -1.116101 2012 -03 -11 09 :30 :00 0.359358 2012 -03 -12 09 :30 :00 -0.475920 2012 -03 -13 09 :30 :00 -0.336570 2012 -03 -14 09 :30 :00 -1.075952 Freq: D, dtype: float64 >>> >>> print(ts.index.tz)None >>> >>> ts_utc = ts.tz_localize('UTC' )>>> ts_utc2012 -03 -09 09 :30 :00 +00 :00 -1.527913 2012 -03 -10 09 :30 :00 +00 :00 -1.116101 2012 -03 -11 09 :30 :00 +00 :00 0.359358 2012 -03 -12 09 :30 :00 +00 :00 -0.475920 2012 -03 -13 09 :30 :00 +00 :00 -0.336570 2012 -03 -14 09 :30 :00 +00 :00 -1.075952 Freq: D, dtype: float64 >>> >>> ts_utc.indexDatetimeIndex(['2012-03-09 09:30:00+00:00' , '2012-03-10 09:30:00+00:00' , '2012-03-11 09:30:00+00:00' , '2012-03-12 09:30:00+00:00' , '2012-03-13 09:30:00+00:00' , '2012-03-14 09:30:00+00:00' ], dtype='datetime64[ns, UTC]' , freq='D' )
时间序列被本地化到某个特定时区后,就可以用 tz_convert
方法将其转换到别的时区了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 >>> import pandas as pd>>> import numpy as np>>> rng = pd.date_range('3/9/2012 9:30' , periods=6 , freq='D' )>>> ts = pd.Series(np.random.randn(len(rng)), index=rng)>>> ts2012 -03 -09 09 :30 :00 0.480303 2012 -03 -10 09 :30 :00 -1.461039 2012 -03 -11 09 :30 :00 -1.512749 2012 -03 -12 09 :30 :00 -2.185421 2012 -03 -13 09 :30 :00 1.657845 2012 -03 -14 09 :30 :00 0.175633 Freq: D, dtype: float64 >>> >>> ts.tz_localize('UTC' ).tz_convert('Asia/Shanghai' )2012 -03 -09 17 :30 :00 +08 :00 0.480303 2012 -03 -10 17 :30 :00 +08 :00 -1.461039 2012 -03 -11 17 :30 :00 +08 :00 -1.512749 2012 -03 -12 17 :30 :00 +08 :00 -2.185421 2012 -03 -13 17 :30 :00 +08 :00 1.657845 2012 -03 -14 17 :30 :00 +08 :00 0.175633 Freq: D, dtype: float64
1 2 3 4 5 这里是一段防爬虫文本,请读者忽略。 本文原创首发于 CSDN,作者 TRHX。 博客首页:https://itrhx.blog.csdn.net/ 本文链接:https://itrhx.blog.csdn.net/article/details/106947061 未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!
【03x00】period 固定时期 【03x01】pandas.Period 固定时期(period)表示的是时间区间,比如数日、数月、数季、数年等。Period 类所表示的就是这种数据类型,其构造函数需要用到一个字符串或整数。
基本语法:
1 2 3 class pandas .Period (value=None, freq=None, ordinal=None, year=None, month=None, quarter=None, day=None, hour=None, minute=None, second=None)
官方文档:https://pandas.pydata.org/docs/reference/api/pandas.Period.html
常用参数:
以下示例中,Period 对象表示的是从2020年1月1日到2020年12月31日之间的整段时间
1 2 3 >>> import pandas as pd>>> pd.Period(2020 , freq='A-DEC' )Period('2020' , 'A-DEC' )
利用加减法对其按照频率进行位移:
1 2 3 4 5 6 7 8 9 10 >>> import pandas as pd>>> obj = pd.Period(2020 , freq='A-DEC' )>>> objPeriod('2020' , 'A-DEC' ) >>> >>> obj + 5 Period('2025' , 'A-DEC' ) >>> >>> obj - 5 Period('2015' , 'A-DEC' )
PeriodIndex 类保存了一组 Period,它可以在任何 pandas 数据结构中被用作轴索引:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 >>> import pandas as pd>>> import numpy as np>>> rng = [pd.Period('2000-01' ), pd.Period('2000-02' ), pd.Period('2000-03' ), pd.Period('2000-04' ), pd.Period('2000-05' ), pd.Period('2000-06' )] >>> obj = pd.Series(np.random.randn(6 ), index=rng)>>> obj2000 -01 0.229092 2000 -02 1.515498 2000 -03 -0.334401 2000 -04 -0.492681 2000 -05 -2.012818 2000 -06 0.338804 Freq: M, dtype: float64 >>> >>> obj.indexPeriodIndex(['2000-01' , '2000-02' , '2000-03' , '2000-04' , '2000-05' , '2000-06' ], dtype='period[M]' , freq='M' )
1 2 3 4 5 6 >>> import pandas as pd>>> values = ['2001Q3' , '2002Q2' , '2003Q1' ]>>> index = pd.PeriodIndex(values, freq='Q-DEC' )>>> indexPeriodIndex(['2001Q3' , '2002Q2' , '2003Q1' ], dtype='period[Q-DEC]' , freq='Q-DEC' ) >>>
【03x02】period_range pandas.period_range
方法可根据指定的频率生成指定长度的 PeriodIndex。
基本语法:
pandas.period_range(start=None, end=None, periods=None, freq=None, name=None) → pandas.core.indexes.period.PeriodIndex
官方文档:https://pandas.pydata.org/docs/reference/api/pandas.period_range.html
常用参数:
参数
描述
start
起始日期
end
结束日期
periods
要生成的时段数
freq
时间戳将具有的偏移量,可以是 str,日期偏移量类型,取值参见【02x02】freq 频率部分取值
name
结果 PeriodIndex 对象名称
简单应用:
1 2 3 4 5 6 7 8 9 10 >>> import pandas as pd>>> pd.period_range(start='2019-01-01' , end='2020-01-01' , freq='M' )PeriodIndex(['2019-01' , '2019-02' , '2019-03' , '2019-04' , '2019-05' , '2019-06' , '2019-07' , '2019-08' , '2019-09' , '2019-10' , '2019-11' , '2019-12' , '2020-01' ], dtype='period[M]' , freq='M' ) >>> >>> pd.period_range(start=pd.Period('2017Q1' , freq='Q' ), end=pd.Period('2017Q2' , freq='Q' ), freq='M' ) PeriodIndex(['2017-03' , '2017-04' , '2017-05' , '2017-06' ], dtype='period[M]' , freq='M' )
【03x03】asfreq 时期频率转换 Period 和 PeriodIndex 对象都可以通过 asfreq 方法被转换成别的频率。
基本语法:PeriodIndex.asfreq(self, *args, **kwargs)
常用参数:
参数
描述
freq
新的频率(偏移量),取值参见【02x02】freq 频率部分取值
how
按照开始或者结束对齐,'E'
or 'END'
or 'FINISH'
;'S'
or 'START'
or 'BEGIN'
应用示例:
1 2 3 4 5 6 7 8 9 10 >>> import pandas as pd>>> pidx = pd.period_range('2010-01-01' , '2015-01-01' , freq='A' )>>> pidxPeriodIndex(['2010' , '2011' , '2012' , '2013' , '2014' , '2015' ], dtype='period[A-DEC]' , freq='A-DEC' ) >>> >>> pidx.asfreq('M' )PeriodIndex(['2010-12' , '2011-12' , '2012-12' , '2013-12' , '2014-12' , '2015-12' ], dtype='period[M]' , freq='M' ) >>> >>> pidx.asfreq('M' , how='S' )PeriodIndex(['2010-01' , '2011-01' , '2012-01' , '2013-01' , '2014-01' , '2015-01' ], dtype='period[M]' , freq='M' )
【03x04】to_period 与 to_timestamp() to_period
方法可以将 Timestamp(时间戳) 转换为 Period(固定时期);
to_timestamp
方法可以将 Period(固定时期)转换为 Timestamp(时间戳) 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 >>> import pandas as pd>>> rng = pd.date_range('2000-01-01' , periods=3 , freq='M' )>>> ts = pd.Series(np.random.randn(3 ), index=rng)>>> ts2000 -01 -31 0.220759 2000 -02 -29 -0.108221 2000 -03 -31 0.819433 Freq: M, dtype: float64 >>> >>> pts = ts.to_period()>>> pts2000 -01 0.220759 2000 -02 -0.108221 2000 -03 0.819433 Freq: M, dtype: float64 >>> >>> pts2 = pts.to_timestamp()>>> pts22000 -01 -01 0.220759 2000 -02 -01 -0.108221 2000 -03 -01 0.819433 Freq: MS, dtype: float64 >>> >>> ts.indexDatetimeIndex(['2000-01-31' , '2000-02-29' , '2000-03-31' ], dtype='datetime64[ns]' , freq='M' ) >>> >>> pts.indexPeriodIndex(['2000-01' , '2000-02' , '2000-03' ], dtype='period[M]' , freq='M' ) >>> >>> pts2.indexDatetimeIndex(['2000-01-01' , '2000-02-01' , '2000-03-01' ], dtype='datetime64[ns]' , freq='MS' )
【04x00】timedelta 时间间隔 【04x01】pandas.Timedelta Timedelta 表示持续时间,即两个日期或时间之间的差。
Timedelta 相当于 Python 的 datetime.timedelta,在大多数情况下两者可以互换。
基本语法:class pandas.Timedelta(value=<object object>, unit=None, **kwargs)
官方文档:https://pandas.pydata.org/docs/reference/api/pandas.Timedelta.html
常用参数:
参数
描述
value
传入的值,可以是 Timedelta,timedelta,np.timedelta64,string 或 integer 对象
unit
用于设置 value 的单位,具体取值参见官方文档
表示两个 datetime 对象之间的时间差:
1 2 3 >>> import pandas as pd>>> pd.to_datetime('2020-6-24' ) - pd.to_datetime('2016-1-1' )Timedelta('1636 days 00:00:00' )
通过字符串传递参数:
1 2 3 >>> import pandas as pd>>> pd.Timedelta('3 days 3 hours 3 minutes 30 seconds' )Timedelta('3 days 03:03:30' )
通过整数传递参数:
1 2 3 >>> import pandas as pd>>> pd.Timedelta(5 ,unit='h' )Timedelta('0 days 05:00:00' )
获取属性:
1 2 3 4 5 6 7 8 9 >>> import pandas as pd>>> obj = pd.Timedelta('3 days 3 hours 3 minutes 30 seconds' )>>> objTimedelta('3 days 03:03:30' ) >>> >>> obj.days3 >>> obj.seconds11010
【04x02】to_timedelta to_timedelta 方法可以将传入的对象转换成 timedelta 对象。
基本语法:pandas.to_timedelta(arg, unit='ns', errors='raise')
官方文档:https://pandas.pydata.org/docs/reference/api/pandas.to_timedelta.html
常用参数:
参数
描述
arg
要转换为 timedelta 的对象,可以是 str,timedelta,list-like 或 Series 对象
unit
用于设置 arg 的单位,具体取值参见官方文档
errors
如果 arg 不满足时间戳的形式,是否会发生异常ignore
:不引发异常,返回原始输入;raise
:无效解析将引发异常(默认);coerce
:无效解析将被设置为NaT
将单个字符串解析为 timedelta 对象:
1 2 3 4 5 6 >>> import pandas as pd>>> pd.to_timedelta('1 days 06:05:01.00003' )Timedelta('1 days 06:05:01.000030' ) >>> >>> pd.to_timedelta('15.5us' )Timedelta('0 days 00:00:00.000015' )
将字符串列表或数组解析为 timedelta 对象:
1 2 3 >>> import pandas as pd>>> pd.to_timedelta(['1 days 06:05:01.00003' , '15.5us' , 'nan' ])TimedeltaIndex(['1 days 06:05:01.000030' , '0 days 00:00:00.000015' , NaT], dtype='timedelta64[ns]' , freq=None )
指定 unit
参数:
1 2 3 4 5 6 >>> import pandas as pd>>> pd.to_timedelta(np.arange(5 ), unit='s' )TimedeltaIndex(['00:00:00' , '00:00:01' , '00:00:02' , '00:00:03' , '00:00:04' ], dtype='timedelta64[ns]' , freq=None ) >>> >>> pd.to_timedelta(np.arange(5 ), unit='d' )TimedeltaIndex(['0 days' , '1 days' , '2 days' , '3 days' , '4 days' ], dtype='timedelta64[ns]' , freq=None )
【04x03】timedelta_range timedelta_range
方法可根据指定的频率生成指定长度的 TimedeltaIndex。
基本语法:
1 2 pandas.timedelta_range(start=None , end=None , periods=None , freq=None , name=None , closed=None ) → pandas.core.indexes.timedeltas.TimedeltaIndex
官方文档:https://pandas.pydata.org/docs/reference/api/pandas.timedelta_range.html
常用参数:
参数
描述
start
开始日期
end
结束日期
periods
int 类型,要生成的时段数
freq
频率字符串,即按照某种特定的频率来生成日期,取值参见【02x02】freq 频率部分取值
name
结果 TimedeltaIndex 的名称
closed
None
:默认值,同时保留开始日期和结束日期'left'
:保留开始日期,不保留结束日期'right'
:保留结束日期,不保留开始日期
应用示例:
1 2 3 >>> import pandas as pd>>> pd.timedelta_range(start='1 day' , periods=4 )TimedeltaIndex(['1 days' , '2 days' , '3 days' , '4 days' ], dtype='timedelta64[ns]' , freq='D' )
closed 参数指定保留哪个端点。默认保留两个端点:
1 2 3 >>> import pandas as pd>>> pd.timedelta_range(start='1 day' , periods=4 , closed='right' )TimedeltaIndex(['2 days' , '3 days' , '4 days' ], dtype='timedelta64[ns]' , freq='D' )
freq 参数指定 TimedeltaIndex 的频率。只接受固定频率,非固定频率如 'M'
将会报错:
1 2 3 4 5 6 7 8 9 10 >>> import pandas as pd>>> pd.timedelta_range(start='1 day' , end='2 days' , freq='6H' )TimedeltaIndex(['1 days 00:00:00' , '1 days 06:00:00' , '1 days 12:00:00' , '1 days 18:00:00' , '2 days 00:00:00' ], dtype='timedelta64[ns]' , freq='6H' ) >>> >>> pd.timedelta_range(start='1 day' , end='2 days' , freq='M' )Traceback (most recent call last): ... ValueError: <MonthEnd> is a non-fixed frequency
【05x00】重采样及频率转换 重采样(resampling)指的是将时间序列从一个频率转换到另一个频率的处理过程。将高频率数据聚合到低频率称为降采样(downsampling),而将低频率数据转换到高频率则称为升采样(upsampling)。并不是所有的重采样都能被划分到这两个大类中。例如,将 W-WED(每周三)转换为 W-FRI 既不是降采样也不是升采样。
Pandas 中提供了 resample 方法来帮助我们实现重采样。Pandas 对象都带有一个 resample 方法,它是各种频率转换工作的主力函数。
基本语法:
1 2 3 4 5 6 7 Series.resample(self, rule, axis=0 , closed: Union[str, NoneType] = None , label: Union[str, NoneType] = None , convention: str = 'start' , kind: Union[str, NoneType] = None , loffset=None , base: int = 0 , on=None , level=None )
1 2 3 4 5 6 7 DataFrame.resample(self, rule, axis=0 , closed: Union[str, NoneType] = None , label: Union[str, NoneType] = None , convention: str = 'start' , kind: Union[str, NoneType] = None , loffset=None , base: int = 0 , on=None , level=None )
常用参数:
参数
描述
rule
axis
重采样的轴,默认 0
closed
在重采样中,各时间段的哪一端是闭合(即包含)的, 除 'M'
、'A'
、'Q'
、'BM'
、'BA'
、'BQ'
和 'W'
默认值为 ‘right’ 外,其他默认值为 ‘left‘
label
在重采样中,如何设置聚合值的标签, right 或 left,默认为 None, 例如,9:30 到 9:35 之间的这 5 分钟会被标记为 9:30 或 9:35
convention
仅用于 PeriodIndex(固定时期),对周期进行重采样,'start'
or 's'
,'end'
or 'e'
on
对于 DataFrame 对象,可用该参数指定重采样后的数据的 index(行索引) 为原数据中的某列
level
对于具有层级索引(MultiIndex)的 DataFrame 对象,可以使用该参数来指定需要在哪个级别上进行重新采样
将序列重采样到三分钟的频率,并将每个频率的值相加:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 >>> import pandas as pd>>> index = pd.date_range('1/1/2000' , periods=9 , freq='T' )>>> series = pd.Series(range(9 ), index=index)>>> series2000 -01 -01 00 :00 :00 0 2000 -01 -01 00 :01 :00 1 2000 -01 -01 00 :02 :00 2 2000 -01 -01 00 :03 :00 3 2000 -01 -01 00 :04 :00 4 2000 -01 -01 00 :05 :00 5 2000 -01 -01 00 :06 :00 6 2000 -01 -01 00 :07 :00 7 2000 -01 -01 00 :08 :00 8 Freq: T, dtype: int64 >>> >>> series.resample('3T' ).sum()2000 -01 -01 00 :00 :00 3 2000 -01 -01 00 :03 :00 12 2000 -01 -01 00 :06 :00 21 Freq: 3 T, dtype: int64
设置 label='right'
,即每个索引 index 会使用靠右侧(较大值)的标签:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 >>> import pandas as pd>>> index = pd.date_range('1/1/2000' , periods=9 , freq='T' )>>> series = pd.Series(range(9 ), index=index)>>> series2000 -01 -01 00 :00 :00 0 2000 -01 -01 00 :01 :00 1 2000 -01 -01 00 :02 :00 2 2000 -01 -01 00 :03 :00 3 2000 -01 -01 00 :04 :00 4 2000 -01 -01 00 :05 :00 5 2000 -01 -01 00 :06 :00 6 2000 -01 -01 00 :07 :00 7 2000 -01 -01 00 :08 :00 8 Freq: T, dtype: int64 >>> >>> series.resample('3T' , label='right' ).sum()2000 -01 -01 00 :03 :00 3 2000 -01 -01 00 :06 :00 12 2000 -01 -01 00 :09 :00 21 Freq: 3 T, dtype: int64
设置 closed='right'
,即结果中会包含原数据中最右侧(较大)的值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 >>> import pandas as pd>>> index = pd.date_range('1/1/2000' , periods=9 , freq='T' )>>> series = pd.Series(range(9 ), index=index)>>> series2000 -01 -01 00 :00 :00 0 2000 -01 -01 00 :01 :00 1 2000 -01 -01 00 :02 :00 2 2000 -01 -01 00 :03 :00 3 2000 -01 -01 00 :04 :00 4 2000 -01 -01 00 :05 :00 5 2000 -01 -01 00 :06 :00 6 2000 -01 -01 00 :07 :00 7 2000 -01 -01 00 :08 :00 8 Freq: T, dtype: int64 >>> >>> series.resample('3T' , label='right' , closed='right' ).sum()2000 -01 -01 00 :00 :00 0 2000 -01 -01 00 :03 :00 6 2000 -01 -01 00 :06 :00 15 2000 -01 -01 00 :09 :00 15 Freq: 3 T, dtype: int64
以下示例将序列重采样到30秒的频率,asfreq()[0:5]
用于选择前5行数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 >>> import pandas as pd>>> index = pd.date_range('1/1/2000' , periods=9 , freq='T' )>>> series = pd.Series(range(9 ), index=index)>>> series2000 -01 -01 00 :00 :00 0 2000 -01 -01 00 :01 :00 1 2000 -01 -01 00 :02 :00 2 2000 -01 -01 00 :03 :00 3 2000 -01 -01 00 :04 :00 4 2000 -01 -01 00 :05 :00 5 2000 -01 -01 00 :06 :00 6 2000 -01 -01 00 :07 :00 7 2000 -01 -01 00 :08 :00 8 Freq: T, dtype: int64 >>> >>> series.resample('30S' ).asfreq()[0 :5 ]2000 -01 -01 00 :00 :00 0.0 2000 -01 -01 00 :00 :30 NaN2000 -01 -01 00 :01 :00 1.0 2000 -01 -01 00 :01 :30 NaN2000 -01 -01 00 :02 :00 2.0 Freq: 30 S, dtype: float64
使用 pad
方法向后填充缺失值(NaN):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 >>> import pandas as pd>>> index = pd.date_range('1/1/2000' , periods=9 , freq='T' )>>> series = pd.Series(range(9 ), index=index)>>> series2000 -01 -01 00 :00 :00 0 2000 -01 -01 00 :01 :00 1 2000 -01 -01 00 :02 :00 2 2000 -01 -01 00 :03 :00 3 2000 -01 -01 00 :04 :00 4 2000 -01 -01 00 :05 :00 5 2000 -01 -01 00 :06 :00 6 2000 -01 -01 00 :07 :00 7 2000 -01 -01 00 :08 :00 8 Freq: T, dtype: int64 >>> >>> series.resample('30S' ).pad()[0 :5 ]2000 -01 -01 00 :00 :00 0 2000 -01 -01 00 :00 :30 0 2000 -01 -01 00 :01 :00 1 2000 -01 -01 00 :01 :30 1 2000 -01 -01 00 :02 :00 2 Freq: 30 S, dtype: int64
使用 bfill
方法向前填充缺失值(NaN):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 >>> import pandas as pd>>> index = pd.date_range('1/1/2000' , periods=9 , freq='T' )>>> series = pd.Series(range(9 ), index=index)>>> series2000 -01 -01 00 :00 :00 0 2000 -01 -01 00 :01 :00 1 2000 -01 -01 00 :02 :00 2 2000 -01 -01 00 :03 :00 3 2000 -01 -01 00 :04 :00 4 2000 -01 -01 00 :05 :00 5 2000 -01 -01 00 :06 :00 6 2000 -01 -01 00 :07 :00 7 2000 -01 -01 00 :08 :00 8 Freq: T, dtype: int64 >>> >>> series.resample('30S' ).bfill()[0 :5 ]2000 -01 -01 00 :00 :00 0 2000 -01 -01 00 :00 :30 1 2000 -01 -01 00 :01 :00 1 2000 -01 -01 00 :01 :30 2 2000 -01 -01 00 :02 :00 2 Freq: 30 S, dtype: int64
通过 apply
方法传递自定义函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 >>> import pandas as pd>>> index = pd.date_range('1/1/2000' , periods=9 , freq='T' )>>> series = pd.Series(range(9 ), index=index)>>> series2000 -01 -01 00 :00 :00 0 2000 -01 -01 00 :01 :00 1 2000 -01 -01 00 :02 :00 2 2000 -01 -01 00 :03 :00 3 2000 -01 -01 00 :04 :00 4 2000 -01 -01 00 :05 :00 5 2000 -01 -01 00 :06 :00 6 2000 -01 -01 00 :07 :00 7 2000 -01 -01 00 :08 :00 8 Freq: T, dtype: int64 >>> >>> def custom_resampler (array_like) : return np.sum(array_like) + 5 >>> series.resample('3T' ).apply(custom_resampler)2000 -01 -01 00 :00 :00 8 2000 -01 -01 00 :03 :00 17 2000 -01 -01 00 :06 :00 26 Freq: 3 T, dtype: int64
convention 参数的应用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 >>> import pandas as pd>>> s = pd.Series([1 , 2 ], index=pd.period_range('2012-01-01' , freq='A' , periods=2 ))>>> s2012 1 2013 2 Freq: A-DEC, dtype: int64 >>> >>> s.resample('Q' , convention='start' ).asfreq()2012 Q1 1.0 2012 Q2 NaN2012 Q3 NaN2012 Q4 NaN2013 Q1 2.0 2013 Q2 NaN2013 Q3 NaN2013 Q4 NaNFreq: Q-DEC, dtype: float64 >>> >>> s.resample('Q' , convention='end' ).asfreq()2012 Q4 1.0 2013 Q1 NaN2013 Q2 NaN2013 Q3 NaN2013 Q4 2.0 Freq: Q-DEC, dtype: float64
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 >>> import pandas as pd>>> q = pd.Series([1 , 2 , 3 , 4 ], index=pd.period_range('2018-01-01' , freq='Q' , periods=4 ))>>> q2018 Q1 1 2018 Q2 2 2018 Q3 3 2018 Q4 4 Freq: Q-DEC, dtype: int64 >>> >>> q.resample('M' , convention='end' ).asfreq()2018 -03 1.0 2018 -04 NaN2018 -05 NaN2018 -06 2.0 2018 -07 NaN2018 -08 NaN2018 -09 3.0 2018 -10 NaN2018 -11 NaN2018 -12 4.0 Freq: M, dtype: float64 >>> >>> q.resample('M' , convention='start' ).asfreq()2018 -01 1.0 2018 -02 NaN2018 -03 NaN2018 -04 2.0 2018 -05 NaN2018 -06 NaN2018 -07 3.0 2018 -08 NaN2018 -09 NaN2018 -10 4.0 2018 -11 NaN2018 -12 NaNFreq: M, dtype: float64
对于 DataFrame 对象,可以使用关键字 on 来指定原数据中的某列为重采样后数据的行索引:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 >>> import pandas as pd>>> d = dict({'price' : [10 , 11 , 9 , 13 , 14 , 18 , 17 , 19 ], 'volume' : [50 , 60 , 40 , 100 , 50 , 100 , 40 , 50 ]}) >>> df = pd.DataFrame(d)>>> df['week_starting' ] = pd.date_range('01/01/2018' , periods=8 , freq='W' )>>> df price volume week_starting 0 10 50 2018 -01 -07 1 11 60 2018 -01 -14 2 9 40 2018 -01 -21 3 13 100 2018 -01 -28 4 14 50 2018 -02 -04 5 18 100 2018 -02 -11 6 17 40 2018 -02 -18 7 19 50 2018 -02 -25 >>> >>> df.resample('M' , on='week_starting' ).mean() price volume week_starting 2018 -01 -31 10.75 62.5 2018 -02 -28 17.00 60.0
对于具有层级索引(MultiIndex)的 DataFrame 对象,可以使用关键字 level
来指定需要在哪个级别上进行重新采样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 >>> import pandas as pd>>> days = pd.date_range('1/1/2000' , periods=4 , freq='D' )>>> d2 = dict({'price' : [10 , 11 , 9 , 13 , 14 , 18 , 17 , 19 ], 'volume' : [50 , 60 , 40 , 100 , 50 , 100 , 40 , 50 ]}) >>> df2 = pd.DataFrame(d2, index=pd.MultiIndex.from_product([days, ['morning' , 'afternoon' ]]))>>> df2 price volume 2000 -01 -01 morning 10 50 afternoon 11 60 2000 -01 -02 morning 9 40 afternoon 13 100 2000 -01 -03 morning 14 50 afternoon 18 100 2000 -01 -04 morning 17 40 afternoon 19 50 >>> >>> df2.resample('D' , level=0 ).sum() price volume 2000 -01 -01 21 110 2000 -01 -02 22 140 2000 -01 -03 32 150 2000 -01 -04 36 90
1 2 3 4 5 这里是一段防爬虫文本,请读者忽略。 本文原创首发于 CSDN,作者 TRHX。 博客首页:https://itrhx.blog.csdn.net/ 本文链接:https://itrhx.blog.csdn.net/article/details/106947061 未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!