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

【Python数据分析】58.时间序列——时区处理


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

  • 可以在以下网站查看,该网站是使用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》翻译整理

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

在Python中,时区语言来源于第三方库 pytz ,公开了Olson数据库,是一个世界时区信息的汇编。

前往pytz库官方文档(https://pypi.org/project/pytz/)查看更多详细信息。

Pandas 封装了 pytz 的功能,因此可以忽略时区名称之外的 API。由于 pandas 对 pytz 有很强的依赖性,因此无须单独安装。可以通过交互方式查看时区名称:

1>>> import pytz
2
3>>> pytz.common_timezones[:5]
4['Africa/Abidjan''Africa/Accra''Africa/Addis_Ababa''Africa/Algiers''Africa/Asmara']

要获取 pytz 的时区对象,需要使用 pytz.timezone

1>>> tz = pytz.timezone("Asia/shanghai")
2>>> tz
3<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>
1.时区本地化和转换:

默认情况下,pandas 中的时间序列是时区简单型的。例如,考虑以下时间序列,索引的 tz 属性是None:

 1>>> dates = pd.date_range("2022-12-12 11:30" , periods=6)
2
3>>> ts = pd.Series(np.arange(len(dates)) , index=dates)
4>>> ts
52022-12-12 11:30:00    0
62022-12-13 11:30:00    1
72022-12-14 11:30:00    2
82022-12-15 11:30:00    3
92022-12-16 11:30:00    4
102022-12-17 11:30:00    5
11Freq: D, dtype: int32
12
13>>> print(ts.index.tz)
14None

可以使用时区集合生成日期范围:

1>>> pd.date_range("2022-12-12 11:30" , periods=6 , tz="UTC")
2DatetimeIndex(['2022-12-12 11:30:00+00:00''2022-12-13 11:30:00+00:00',
3               '2022-12-14 11:30:00+00:00''2022-12-15 11:30:00+00:00',
4               '2022-12-16 11:30:00+00:00''2022-12-17 11:30:00+00:00'],
5              dtype='datetime64[ns, UTC]', freq='D')

通过tz_localize 方法可以从简单时区转换到本地化时区:

 1>>> ts
22022-12-12 11:30:00    0
32022-12-13 11:30:00    1
42022-12-14 11:30:00    2
52022-12-15 11:30:00    3
62022-12-16 11:30:00    4
72022-12-17 11:30:00    5
8Freq: D, dtype: int32
9
10>>> ts_utc = ts.tz_localize("UTC")
11>>> ts_utc
122022-12-12 11:30:00+00:00    0
132022-12-13 11:30:00+00:00    1
142022-12-14 11:30:00+00:00    2
152022-12-15 11:30:00+00:00    3
162022-12-16 11:30:00+00:00    4
172022-12-17 11:30:00+00:00    5
18Freq: D, dtype: int32
19
20>>> ts_utc.index
21DatetimeIndex(['2022-12-12 11:30:00+00:00''2022-12-13 11:30:00+00:00',
22               '2022-12-14 11:30:00+00:00''2022-12-15 11:30:00+00:00',
23               '2022-12-16 11:30:00+00:00''2022-12-17 11:30:00+00:00'],
24              dtype='datetime64[ns, UTC]', freq='D')

一旦时间序列被本地化为某个特定的时区,则可以通过 tz_convert 将其转换为另一个时区:

1>>> ts_utc.tz_convert("Asia/shanghai")
22022-12-12 19:30:00+08:00    0
32022-12-13 19:30:00+08:00    1
42022-12-14 19:30:00+08:00    2
52022-12-15 19:30:00+08:00    3
62022-12-16 19:30:00+08:00    4
72022-12-17 19:30:00+08:00    5
8Freq: D, dtype: int32

tz_localizetz_convert 也是DatetimeIndex 的实例方法:

 1>>> ts.index
2DatetimeIndex(['2022-12-12 11:30:00''2022-12-13 11:30:00',
3               '2022-12-14 11:30:00''2022-12-15 11:30:00',
4               '2022-12-16 11:30:00''2022-12-17 11:30:00'],
5              dtype='datetime64[ns]', freq='D')
6
7>>> ts_utc_index = ts.index.tz_localize("UTC")
8>>> ts_utc_index
9DatetimeIndex(['2022-12-12 11:30:00+00:00''2022-12-13 11:30:00+00:00',
10               '2022-12-14 11:30:00+00:00''2022-12-15 11:30:00+00:00',
11               '2022-12-16 11:30:00+00:00''2022-12-17 11:30:00+00:00'],
12              dtype='datetime64[ns, UTC]', freq='D')
13
14>>> ts_utc_index.tz_convert("Asia/shanghai")
15DatetimeIndex(['2022-12-12 19:30:00+08:00''2022-12-13 19:30:00+08:00',
16               '2022-12-14 19:30:00+08:00''2022-12-15 19:30:00+08:00',
17               '2022-12-16 19:30:00+08:00''2022-12-17 19:30:00+08:00'],
18              dtype='datetime64[ns, Asia/Shanghai]', freq='D')
2.时区感知时间戳对象的操作:

与时间序列和日期范围类似,单个 Timestamp 对象同样也可以从简单时间戳本地化为时区感知时间戳,并从一个时区转换为另一个时区:

 1>>> stamp = pd.Timestamp("2022-12-12 11:30")
2>>> stamp
3Timestamp('2022-12-12 11:30:00')
4
5>>> stamp_utc = stamp.tz_localize("UTC")
6>>> stamp_utc
7Timestamp('2022-12-12 11:30:00+0000', tz='UTC')
8
9>>> stamp_utc.tz_convert("Asia/shanghai")
10Timestamp('2022-12-12 19:30:00+0800', tz='Asia/Shanghai')

也可以在创建时间戳时传递时区:

1>>> stamp_china = pd.Timestamp("2022-12-12 11:30", tz="Asia/shanghai")
2>>> stamp_china
3Timestamp('2022-12-12 11:30:00+0800', tz='Asia/Shanghai')

时区感知的Timestamp 对象内部存储了一个 Unix 纪元(1970 年 1 月 1 日)至今的纳秒数量UTC时间戳数值,该数值在时区转换时时不变的:

1>>> stamp_utc.value
21670844600000000000
3
4>>> stamp_utc.tz_convert("Asia/shanghai").value
51670844600000000000

在使用Pandas中的 DateOffset 对象进行时间算术时,pandas 会尽可能遵守夏令时。

1>>> from pandas.tseries.offsets import Hour
2
3>>> stamp = pd.Timestamp("2022-12-12 11:30", tz="Asia/shanghai")
4>>> stamp
5Timestamp('2022-12-12 11:30:00+0800', tz='Asia/Shanghai')
6
7>>> stamp + Hour()
8Timestamp('2022-12-12 12:30:00+0800', tz='Asia/Shanghai')
3.不同时区间的操作:

如果两个时区不同的时间序列需要联合操作,那么结果将是UTC时间的。由于时间戳以UTC格式存储,这是一个简单的操作,不需要转换:

 1>>> dates = pd.date_range("2022-12-12 11:30", periods=10, freq="B")
2>>> dates
3DatetimeIndex(['2022-12-12 11:30:00''2022-12-13 11:30:00',
4               '2022-12-14 11:30:00''2022-12-15 11:30:00',
5               '2022-12-16 11:30:00''2022-12-19 11:30:00',
6               '2022-12-20 11:30:00''2022-12-21 11:30:00',
7               '2022-12-22 11:30:00''2022-12-23 11:30:00'],
8              dtype='datetime64[ns]', freq='B')
9
10>>> ts = pd.Series(np.arange(len(dates)), index=dates)
11>>> ts
122022-12-12 11:30:00    0
132022-12-13 11:30:00    1
142022-12-14 11:30:00    2
152022-12-15 11:30:00    3
162022-12-16 11:30:00    4
172022-12-19 11:30:00    5
182022-12-20 11:30:00    6
192022-12-21 11:30:00    7
202022-12-22 11:30:00    8
212022-12-23 11:30:00    9
22Freq: B, dtype: int32
23
24>>> ts1 = ts[:7].tz_localize("Asia/shanghai")
25>>> ts1
262022-12-12 11:30:00+08:00    0
272022-12-13 11:30:00+08:00    1
282022-12-14 11:30:00+08:00    2
292022-12-15 11:30:00+08:00    3
302022-12-16 11:30:00+08:00    4
312022-12-19 11:30:00+08:00    5
322022-12-20 11:30:00+08:00    6
33dtype: int32
34
35>>> ts2 = ts1[2:].tz_convert("Europe/Moscow")
36>>> ts2
372022-12-14 06:30:00+03:00    2
382022-12-15 06:30:00+03:00    3
392022-12-16 06:30:00+03:00    4
402022-12-19 06:30:00+03:00    5
412022-12-20 06:30:00+03:00    6
42dtype: int32
43
44>>> result = ts1 + ts2
45>>> result
462022-12-12 03:30:00+00:00     NaN
472022-12-13 03:30:00+00:00     NaN
482022-12-14 03:30:00+00:00     4.0
492022-12-15 03:30:00+00:00     6.0
502022-12-16 03:30:00+00:00     8.0
512022-12-19 03:30:00+00:00    10.0
522022-12-20 03:30:00+00:00    12.0
53dtype: float64
54>>> result.index
55DatetimeIndex(['2022-12-12 03:30:00+00:00''2022-12-13 03:30:00+00:00',
56               '2022-12-14 03:30:00+00:00''2022-12-15 03:30:00+00:00',
57               '2022-12-16 03:30:00+00:00''2022-12-19 03:30:00+00:00',
58               '2022-12-20 03:30:00+00:00'],
59              dtype='datetime64[ns, UTC]', freq=None)


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

RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments