8

Python 数据分析三剑客之 Pandas(九):时间序列

 3 years ago
source link: https://www.itrhx.com/2020/06/25/A87-Pandas-09/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Pandas 系列文章:


NumPy 专栏】【Pandas 专栏】【Matplotlib 专栏

推荐学习资料与网站:

NumPy 中文网】【Pandas 中文网】【Matplotlib 中文网】【NumPy、Matplotlib、Pandas 速查表


这里是一段防爬虫文本,请读者忽略。
本文原创首发于 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

基本语法:

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)

简单示例:

>>> import pandas as pd
>>> pd.Timestamp('2017-01-01T12')
Timestamp('2017-01-01 12:00:00')

设置 unit='s',即待转换对象单位为秒:

>>> import pandas as pd
>>> pd.Timestamp(1513393355.5, unit='s')
Timestamp('2017-12-16 03:02:35.500000')

使用 tz 参数设置时区:

>>> import pandas as pd
>>> pd.Timestamp(1513393355, unit='s', tz='US/Pacific')
Timestamp('2017-12-15 19:02:35-0800', tz='US/Pacific')

单独设置年月日:

>>> 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 库提供了日期和时间处理方法,利用 strstrftime 方法可以将 datetime 对象转化成字符串,具体用法可参见【Python 标准库学习】日期和时间处理库 — datetime

>>> from datetime import datetime
>>> stamp = datetime(2020, 6, 24)
>>> stamp
datetime.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(时间戳) 对象:
>>> 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')

基本语法:

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)

简单应用:

>>> 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]

设置 formaterrors 参数:

>>> 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 参数:

>>> 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。

基本语法:

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':保留结束日期,不保留开始日期

简单示例:

>>> 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 参数:

>>> 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个月按照每月最后一个日历日的频率生成日期:

>>> 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 参数设置时区:

>>> 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 参数,在生成时间戳之前对其进行格式化操作:

>>> 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 参数:

>>> 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 对象的切片方法对其进行索引:

>>> 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)
>>>
>>> obj
2011-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.index
DatetimeIndex(['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)

另外还可以传入一个可以被解释为日期的字符串,或者只需传入“年”或“年月”即可轻松选取数据的切片:

>>> import pandas as pd
>>> import numpy as np
>>> obj = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
>>> obj
2000-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 方法用于执行单纯的前移或后移操作,保持索引不变:

>>> 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'))
>>> obj
2000-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 NaN
2000-02-29 NaN
2000-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 NaN
2000-04-30 NaN
Freq: M, dtype: float64

因为简单的移位操作不会修改索引,所以部分数据会被丢弃并引入 NaN(缺失值)。因此,如果频率已知,则可以将其传给 shift 以便实现对时间戳进行位移而不是对数据进行简单位移:

>>> 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'))
>>> obj
2000-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 类表示:

>>> from pandas.tseries.offsets import Hour, Minute
>>> hour = Hour()
>>> hour
<Hour>
>>>
>>> four_hours = Hour(4)
>>> four_hours
<4 * Hours>

一般来说,无需明确创建这样的对象,只需使用诸如 "H""4H" 这样的字符串别名即可。在基础频率前面放上一个整数即可创建倍数:

>>> 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')

大部分偏移量对象都可通过加法进行连接:

>>> from pandas.tseries.offsets import Hour, Minute
>>> Hour(2) + Minute(30)
<150 * Minutes>

对于 freq 参数也可以传入频率字符串(如 "2h30min"),这种字符串可以被高效地解析为等效的表达式:

>>> 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 对象上:

>>> from pandas.tseries.offsets import Day, MonthEnd
>>> now = datetime(2011, 11, 17)
>>> now + 3 * Day()
Timestamp('2011-11-20 00:00:00')

如果加的是锚点偏移量,比如 MonthEnd,第一次增量会将原日期向前滚动到符合频率规则的下一个日期:

>>> 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 方法,可明确地将日期向前或向后滚动:

>>> 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 方法结合使用:

>>> 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'))
>>> obj
2000-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: 4D, 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 中获取时区对象:

>>> 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> # 表示与 UTC 时间相差8小时6分

date_range 方法中,tz 参数用于指定时区,默认为 None,可以使用 tz_localize 方法将其进行本地化时区转换,如下示例中,将无时区转本地化 UTC 时区:

>>> 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)
>>> ts
2012-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_utc
2012-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.index
DatetimeIndex(['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 方法将其转换到别的时区了:

>>> 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)
>>> ts
2012-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

这里是一段防爬虫文本,请读者忽略。
本文原创首发于 CSDN,作者 TRHX。
博客首页:https://itrhx.blog.csdn.net/
本文链接:https://itrhx.blog.csdn.net/article/details/106947061
未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!

【03x00】period 固定时期

【03x01】pandas.Period

固定时期(period)表示的是时间区间,比如数日、数月、数季、数年等。Period 类所表示的就是这种数据类型,其构造函数需要用到一个字符串或整数。

基本语法:

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

常用参数:

参数 描述 value 时间段 freq 时间戳将具有的偏移量,可以是 str,日期偏移量类型,取值参见【02x02】freq 频率部分取值

以下示例中,Period 对象表示的是从2020年1月1日到2020年12月31日之间的整段时间

>>> import pandas as pd
>>> pd.Period(2020, freq='A-DEC')
Period('2020', 'A-DEC')

利用加减法对其按照频率进行位移:

>>> import pandas as pd
>>> obj = pd.Period(2020, freq='A-DEC')
>>> obj
Period('2020', 'A-DEC')
>>>
>>> obj + 5
Period('2025', 'A-DEC')
>>>
>>> obj - 5
Period('2015', 'A-DEC')

PeriodIndex 类保存了一组 Period,它可以在任何 pandas 数据结构中被用作轴索引:

>>> 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)
>>> obj
2000-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.index
PeriodIndex(['2000-01', '2000-02', '2000-03', '2000-04', '2000-05', '2000-06'], dtype='period[M]', freq='M')
>>> import pandas as pd
>>> values = ['2001Q3', '2002Q2', '2003Q1']
>>> index = pd.PeriodIndex(values, freq='Q-DEC')
>>> index
PeriodIndex(['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 对象名称

简单应用:

>>> 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'

应用示例:

>>> import pandas as pd
>>> pidx = pd.period_range('2010-01-01', '2015-01-01', freq='A')
>>> pidx
PeriodIndex(['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(时间戳) 。

>>> import pandas as pd
>>> rng = pd.date_range('2000-01-01', periods=3, freq='M')
>>> ts = pd.Series(np.random.randn(3), index=rng)
>>> ts
2000-01-31 0.220759
2000-02-29 -0.108221
2000-03-31 0.819433
Freq: M, dtype: float64
>>>
>>> pts = ts.to_period()
>>> pts
2000-01 0.220759
2000-02 -0.108221
2000-03 0.819433
Freq: M, dtype: float64
>>>
>>> pts2 = pts.to_timestamp()
>>> pts2
2000-01-01 0.220759
2000-02-01 -0.108221
2000-03-01 0.819433
Freq: MS, dtype: float64
>>>
>>> ts.index
DatetimeIndex(['2000-01-31', '2000-02-29', '2000-03-31'], dtype='datetime64[ns]', freq='M')
>>>
>>> pts.index
PeriodIndex(['2000-01', '2000-02', '2000-03'], dtype='period[M]', freq='M')
>>>
>>> pts2.index
DatetimeIndex(['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 对象之间的时间差:

>>> import pandas as pd
>>> pd.to_datetime('2020-6-24') - pd.to_datetime('2016-1-1')
Timedelta('1636 days 00:00:00')

通过字符串传递参数:

>>> import pandas as pd
>>> pd.Timedelta('3 days 3 hours 3 minutes 30 seconds')
Timedelta('3 days 03:03:30')

通过整数传递参数:

>>> import pandas as pd
>>> pd.Timedelta(5,unit='h')
Timedelta('0 days 05:00:00')

获取属性:

>>> import pandas as pd
>>> obj = pd.Timedelta('3 days 3 hours 3 minutes 30 seconds')
>>> obj
Timedelta('3 days 03:03:30')
>>>
>>> obj.days
3
>>> obj.seconds
11010

【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 对象:

>>> 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 对象:

>>> 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 参数:

>>> 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。

基本语法:

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':保留结束日期,不保留开始日期

应用示例:

>>> 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 参数指定保留哪个端点。默认保留两个端点:

>>> 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' 将会报错:

>>> 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 方法,它是各种频率转换工作的主力函数。

基本语法:

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)
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 对象,可以使用该参数来指定需要在哪个级别上进行重新采样

将序列重采样到三分钟的频率,并将每个频率的值相加:

>>> import pandas as pd
>>> index = pd.date_range('1/1/2000', periods=9, freq='T')
>>> series = pd.Series(range(9), index=index)
>>> series
2000-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: 3T, dtype: int64

设置 label='right',即每个索引 index 会使用靠右侧(较大值)的标签:

>>> import pandas as pd
>>> index = pd.date_range('1/1/2000', periods=9, freq='T')
>>> series = pd.Series(range(9), index=index)
>>> series
2000-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: 3T, dtype: int64

设置 closed='right',即结果中会包含原数据中最右侧(较大)的值:

>>> import pandas as pd
>>> index = pd.date_range('1/1/2000', periods=9, freq='T')
>>> series = pd.Series(range(9), index=index)
>>> series
2000-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: 3T, dtype: int64

以下示例将序列重采样到30秒的频率,asfreq()[0:5] 用于选择前5行数据:

>>> import pandas as pd
>>> index = pd.date_range('1/1/2000', periods=9, freq='T')
>>> series = pd.Series(range(9), index=index)
>>> series
2000-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 NaN
2000-01-01 00:01:00 1.0
2000-01-01 00:01:30 NaN
2000-01-01 00:02:00 2.0
Freq: 30S, dtype: float64

使用 pad 方法向后填充缺失值(NaN):

>>> import pandas as pd
>>> index = pd.date_range('1/1/2000', periods=9, freq='T')
>>> series = pd.Series(range(9), index=index)
>>> series
2000-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: 30S, dtype: int64

使用 bfill 方法向前填充缺失值(NaN):

>>> import pandas as pd
>>> index = pd.date_range('1/1/2000', periods=9, freq='T')
>>> series = pd.Series(range(9), index=index)
>>> series
2000-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: 30S, dtype: int64

通过 apply 方法传递自定义函数:

>>> import pandas as pd
>>> index = pd.date_range('1/1/2000', periods=9, freq='T')
>>> series = pd.Series(range(9), index=index)
>>> series
2000-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: 3T, dtype: int64

convention 参数的应用:

>>> import pandas as pd
>>> s = pd.Series([1, 2], index=pd.period_range('2012-01-01', freq='A', periods=2))
>>> s
2012 1
2013 2
Freq: A-DEC, dtype: int64
>>>
>>> s.resample('Q', convention='start').asfreq()
2012Q1 1.0
2012Q2 NaN
2012Q3 NaN
2012Q4 NaN
2013Q1 2.0
2013Q2 NaN
2013Q3 NaN
2013Q4 NaN
Freq: Q-DEC, dtype: float64
>>>
>>> s.resample('Q', convention='end').asfreq()
2012Q4 1.0
2013Q1 NaN
2013Q2 NaN
2013Q3 NaN
2013Q4 2.0
Freq: Q-DEC, dtype: float64
>>> import pandas as pd
>>> q = pd.Series([1, 2, 3, 4], index=pd.period_range('2018-01-01', freq='Q', periods=4))
>>> q
2018Q1 1
2018Q2 2
2018Q3 3
2018Q4 4
Freq: Q-DEC, dtype: int64
>>>
>>> q.resample('M', convention='end').asfreq()
2018-03 1.0
2018-04 NaN
2018-05 NaN
2018-06 2.0
2018-07 NaN
2018-08 NaN
2018-09 3.0
2018-10 NaN
2018-11 NaN
2018-12 4.0
Freq: M, dtype: float64
>>>
>>> q.resample('M', convention='start').asfreq()
2018-01 1.0
2018-02 NaN
2018-03 NaN
2018-04 2.0
2018-05 NaN
2018-06 NaN
2018-07 3.0
2018-08 NaN
2018-09 NaN
2018-10 4.0
2018-11 NaN
2018-12 NaN
Freq: M, dtype: float64

对于 DataFrame 对象,可以使用关键字 on 来指定原数据中的某列为重采样后数据的行索引:

>>> 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 来指定需要在哪个级别上进行重新采样:

>>> 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

这里是一段防爬虫文本,请读者忽略。
本文原创首发于 CSDN,作者 TRHX。
博客首页:https://itrhx.blog.csdn.net/
本文链接:https://itrhx.blog.csdn.net/article/details/106947061
未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK