首页Python【Python数据分析】5...

【Python数据分析】59.时间序列——时间区间和区间算术1


本系列文章配套代码获取有以下三种途径:

  • 可以在以下网站查看,该网站是使用JupyterLite搭建的web端Jupyter环境,因此无需在本地安装运行环境即可使用,首次运行浏览器需要下载一些配置文件(大约20M):

https://returu.github.io/Python_Data_Analysis/lab/index.html
链接:https://pan.baidu.com/s/1MYkeYeVAIRqbxezQECHwcA?pwd=mnsj 提取码:mnsj
  • 前往GitHub详情页面,单击 code 按钮,选择Download ZIP选项:
https://github.com/returu/Python_Data_Analysis

根据《Python for Data Analysis 3rd Edition》翻译整理

—————————————————–

时间区间表示的是时间范围,例如天、月、季度或年。pandas.Period 类表示此数据类型,需要使用一个字符串或数字以及有效的频率:

1# 在这种情况下,Period 对象表示从 2022 年 1 月 1 日到 2022 年 12 月 31 日(含)的完整时间跨度。
2>>> p = pd.Period("2022" , freq="A-DEC")
3>>> p
4Period('2022''A-DEC')

在时间段上增加或减去整数可以很方便的根据它们的频率进行移位:

1>>> p + 3
2Period('2025''A-DEC')
3
4>>> p - 2
5Period('2020''A-DEC')

果两个区间具有相同的频率,则它们的差值是它们之间的单位数:

1>>> pd.Period("2024", freq="A-DEC") - p
2<2 * YearEnds: month=12>

可以使用 period_range 函数构造规则的区间序列:

1>>> periods = pd.period_range("2022-1-1" , "2022-12-12" , freq="M")
2>>> periods
3PeriodIndex(['2022-01''2022-02''2022-03''2022-04''2022-05''2022-06',
4             '2022-07''2022-08''2022-09''2022-10''2022-11''2022-12'],
5            dtype='period[M]')

PeriodIndex 类存储的是区间的序列,可以作为任意pandas数据结构中的轴索引:

 1>>> pd.Series(np.arange(len(periods)), index=periods)
22022-01     0
32022-02     1
42022-03     2
52022-04     3
62022-05     4
72022-06     5
82022-07     6
92022-08     7
102022-09     8
112022-10     9
122022-11    10
132022-12    11
14Freq: M, dtype: int32

如果你有一个字符串数组,也可以使用 PeriodIndex 类,它的所有值都是时间区间:

1>>> values = ["2001Q3""2002Q2""2003Q1"]
2
3>>> index = pd.PeriodIndex(values, freq="Q-DEC")
4>>> index
5PeriodIndex(['2001Q3''2002Q2''2003Q1'], dtype='period[Q-DEC]')
1.区间频率转换:

PeriodsPeriodIndex 对象可以使用它们的 asfreq 方法将其转换为另一个频率。

例如,假设我们有一个年度区间,并希望在年初或年底将其转换为月度区间。可以这样做:

 1# Period 对象表示从 2022 年 1 月 1 日到 2022 年 12 月 31 日(含)的完整时间跨度。
2>>> p = pd.Period("2022", freq="A-DEC")
3>>> p
4Period('2022''A-DEC')
5
6>>> p.asfreq("M",how="start")
7Period('2022-01''M')
8
9>>> p.asfreq("M",how="end")
10Period('2022-12''M')
11
12>>> p.asfreq("M")
13Period('2022-12''M')

区间频率转换示意图如下所示:

对于除了12月份以外的一个月结束的财政年度,相应的每月分期是不同的:

1>>> p = pd.Period("2022", freq="A-MAY")
2>>> p
3Period('2022''A-MAY')
4
5>>> p.asfreq("M",how="start")
6Period('2021-06''M')
7
8>>> p.asfreq("M",how="end")
9Period('2022-05''M')

区间频率转换示意图如下所示:

当你从高频转换为低频时,pandas会根据子区间的所属来决定父区间。

例如,在"A-MAY"频率中,"Aug-2021"是2022区间的一部分(可以参看上图分析):

1>>> p = pd.Period("Aug-2021""M")
2
3>>> p.asfreq("A-MAY")
4Period('2022''A-MAY')

可以使用相同的语义转换完整的PeriodIndex 对象或时间序列。

例如,使用“M”频率,年度期间将被替换为对应于每个年度区间的第一个月的月度期间。

 1>>> periods = pd.period_range("2019""2022", freq="A-DEC")
2>>> periods
3PeriodIndex(['2019''2020''2021''2022'], dtype='period[A-DEC]')
4
5>>> ts = pd.Series(np.arange(len(periods)), index=periods)
6>>> ts
72019    0
82020    1
92021    2
102022    3
11Freq: A-DEC, dtype: int32
12
13>>> ts.asfreq("M" , how="start")
142019-01    0
152020-01    1
162021-01    2
172022-01    3
18Freq: M, dtype: int32

此处,使用“B”频率表明我们想要的区间末端,年度区间将被替换为每年最后一个工作日:

1>>> ts.asfreq("B", how="end")
22019-12-31    0
32020-12-31    1
42021-12-31    2
52022-12-30    3
6Freq: B, dtype: int32
2.季度区间频率:

季度数据是会计、金融和其他领域的标准。许多季度数据是相对于财政年度结束报告的,通常是一年中 12 个月之一的最后一个日历日或工作日。

因此,2022Q4 期间根据财政年度结束具有不同的含义。pandas 支持所有 12 种可能的季度频率,从 Q-JANQ-DEC

1>>> p = pd.Period("2022Q4", freq="Q-JAN")
2>>> p
3Period('2022Q4''Q-JAN')

对于在 1 月结束的财政年度,2022Q4 是从 2021 年 11 月到 2022 年 1 月,可以通过转换为每日频率来检查:

1>>> p.asfreq("D", how="start")
2Period('2021-11-01''D')
3
4>>> p.asfreq("D", how="end")
5Period('2022-01-31''D')

不同的季度频率示意图如下所示:

因此,可以进行简单的区间运算。

例如,获取在本季度的倒数第二个工作日下午 4 点的时间戳:

1>>> p4pm = (p.asfreq("B", how="end") - 1).asfreq("T", how="start") + 16 * 60
2>>> p4pm
3Period('2022-01-28 16:00''T')
4
5# to_timestamp 方法默认返回周期开始时的时间戳。
6>>> p4pm.to_timestamp()
7Timestamp('2022-01-28 16:00:00')

可以使用 pandas.period_range 生成季度序列,其算法也是相同的:

 1>>> periods = pd.period_range("2021Q3""2022Q4", freq="Q-JAN")
2>>> periods
3PeriodIndex(['2021Q3''2021Q4''2022Q1''2022Q2''2022Q3''2022Q4'], dtype='period[Q-JAN]')
4
5>>> ts = pd.Series(np.arange(len(periods)), index=periods)
6>>> ts
72021Q3    0
82021Q4    1
92022Q1    2
102022Q2    3
112022Q3    4
122022Q4    5
13Freq: Q-JAN, dtype: int32
14
15>>> new_periods = (periods.asfreq("B""end") - 1).asfreq("H""start") + 16
16>>> new_periods
17PeriodIndex(['2020-10-29 16:00''2021-01-28 16:00''2021-04-29 16:00',
18             '2021-07-29 16:00''2021-10-28 16:00''2022-01-28 16:00'],
19            dtype='period[H]')
20
21>>> ts.index = new_periods.to_timestamp()
22
23>>> ts
242020-10-29 16:00:00    0
252021-01-28 16:00:00    1
262021-04-29 16:00:00    2
272021-07-29 16:00:00    3
282021-10-28 16:00:00    4
292022-01-28 16:00:00    5
30dtype: int32


本篇文章来源于微信公众号: 码农设计师

RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments