本系列文章配套代码获取有以下三种途径:
-
可以在以下网站查看,该网站是使用JupyterLite搭建的web端Jupyter环境,因此无需在本地安装运行环境即可使用,首次运行浏览器需要下载一些配置文件(大约20M):
https://returu.github.io/Python_Data_Analysis/lab/index.html
-
也可以通过百度网盘获取,需要在本地配置代码运行环境,环境配置可以查看【Python基础】2.搭建Python开发环境:
链接: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>
默认情况下,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_localize
和 tz_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')
与时间序列和日期范围类似,单个 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')
如果两个时区不同的时间序列需要联合操作,那么结果将是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)
本篇文章来源于微信公众号: 码农设计师