文章数据
收藏(次)
【python数据分析】第十一章 时间序列-3
可能使用的包
from datetime import datetime
from datetime import timedelta
from dateutil.parser import parse
import pandas as pd
import numpy as np
--------------------------------------------------------------------------------
移动(超前和滞后)数据:
Series DataFrame 都有这个方法,index 位置不变,数据移动
--------------------------------------------------------------------------------
f = pd.Series([1,2,3,4], index=pd.date_range('2020-10-1', periods=4, freq='M'))
f.shift(2) # 数据后移, 3,4 出界丢弃,空出的补 NA
f.shift(-2) # 前移
f / f.shift(1) - 1
--------------------------------------------------------------------------------
# If `freq` is specified then the index values are shifted but the data is not realigned.
f.shift(2, freq='M') # 参数 `freq` 指定后,时间轴会移动,但是数据不会被重新调整
--------------------------------------------------------------------------------
通过偏移量对日期进行位移
--------------------------------------------------------------------------------
offset = pd.tseries.offsets.MonthEnd()
offset.rollforward(datetime(2020, 9, 11)) # offset表示月最后一天,时间向后滚动,输出 Timestamp('2020-09-30 00:00:00')
offset.rollback(datetime(2020, 9, 11)) # 向前滚动到月底,输出: Timestamp('2020-08-31 00:00:00')
--------------------------------------------------------------------------------
ts = pd.Series(np.random.randn(20), index=pd.date_range('1/15/2000', periods=20, freq='4d'))
ts 输出:
2000-01-15 -0.705228
2000-01-19 0.065851
2000-01-23 0.627075
2000-01-27 -0.586801
2000-01-31 -1.223137
2000-02-04 -1.399791
2000-02-08 0.343565
2000-02-12 2.525730
2000-02-16 1.384145
2000-02-20 0.409905
2000-02-24 0.175886
2000-02-28 2.314803
2000-03-03 -1.278393
2000-03-07 1.603629
2000-03-11 1.389599
2000-03-15 0.529590
2000-03-19 1.333584
2000-03-23 -0.207778
2000-03-27 2.134428
2000-03-31 -0.345111
Freq: 4D, dtype: float64
offset = pd.tseries.offsets.MonthEnd() # 创建一个时间点,每月月末
ts.groupby(offset.rollforward).sum() # 向月末滚动,分组,也就是每月数据是一个组,这个好理解
ts.groupby(offset.rollback).sum() # 向上一个月的月末滚动,这个计算周期有点费解
输出:
1999-12-31 -0.599102 数据区间是这个【1999-12-31 - 2000-1-30】
2000-01-31 4.531106 数据区间是 【2000-1-30 - 2000-2-28】
2000-02-29 5.504658 数据区间是 【2000-2-29 - 2000-3-30】
2000-03-31 -0.345111 ....
dtype: float64
--------------------------------------------------------------------------------
时区处理
--------------------------------------------------------------------------------
import pytz
pytz.common_timezones[-5:]
输出:
['US/Eastern', 'US/Hawaii', 'US/Mountain', 'US/Pacific', 'UTC']
pytz.timezone('Asia/ShangHai') # 输出 <DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>
pytz.timezone('UTC') # 标准时间
--------------------------------------------------------------------------------
在Python中,时区信息来自第三方库pytz,它使Python可以使用Olson数据库(汇编了世界时区信息)
由于pandas包装了pytz的功能,因此你可以不用记忆其API,只要记得时区的名称即可。
--------------------------------------------------------------------------------
rng = pd.date_range('3/9/2012 9:30', periods=6, freq='D') # 没有时区信息
ts = pd.Series(np.random.randn(len(rng)), index=rng)
ts.tz_localize('UTC') # 转换一下带有时区的时间
2012-03-09 09:30:00+00:00 0.838980
2012-03-10 09:30:00+00:00 -0.701154
2012-03-11 09:30:00+00:00 -0.019127
2012-03-12 09:30:00+00:00 1.622394
2012-03-13 09:30:00+00:00 1.285858
2012-03-14 09:30:00+00:00 0.767050
Freq: D, dtype: float64
--------------------------------------------------------------------------------
也可以直接创建带有时区的时间
pd.date_range('3/9/2012 9:30', periods=10, freq='D', tz='UTC')
--------------------------------------------------------------------------------
转换成其他时区的时间
ts_utc.tz_convert('America/New_York')
--------------------------------------------------------------------------------
stamp = pd.Timestamp('2011-03-12 04:00')
stamp_utc = stamp.tz_localize('utc')
stamp_utc.tz_convert('America/New_York')
# 输出: Timestamp('2011-03-11 23:00:00-0500', tz='America/New_York')
--------------------------------------------------------------------------------
创建时指定时区: stamp_moscow = pd.Timestamp('2011-03-12 04:00', tz='Europe/Moscow')
stamp_utc.tz_convert('America/New_York').value # 1970.1.1 到指定时间的 纳秒数(10^-9)
--------------------------------------------------------------------------------
如果两个时间序列的时区不同,在将它们合并到一起时,最终结果就会是UTC。
rng = pd.date_range('3/7/2012 9:30', periods=10, freq='B')
ts = pd.Series(np.random.randn(len(rng)), index=rng)
ts1 = ts[:7].tz_localize('Europe/London')
ts2 = ts1[2:].tz_convert('Europe/Moscow')
result = ts1 + ts2
不同时区时间运输和匹配的时候应该是 pd 把时间先转成 UTC ,然后运算
--------------------------------------------------------------------------------
时期及其算术运算
--------------------------------------------------------------------------------
p = pd.Period(2007, freq='A-DEC')
这个Period对象表示的是从2007年1月1日到2007年12月31日之间的整段时间。
只需对Period对象加上或减去一个整数即可达到根据其频率进行位移的效果
--------------------------------------------------------------------------------
p + 5
输出:Period('2012', 'A-DEC')
p - 2
输出: Period('2005', 'A-DEC')
pd.Period('2014', freq='A-DEC') - p
输出: 7
rng = pd.period_range('2000-01-01', '2000-06-30', freq='M')
输出:
PeriodIndex(['2000-01', '2000-02', '2000-03', '2000-04', '2000-05', '2000-06']
--------------------------------------------------------------------------------
时期的频率转换
p = pd.Period('2007', freq='A-DEC')
p 输出:Period('2007', 'A-DEC')
p.asfreq('M', how='start')
输出: Period('2007-01', 'M')
p.asfreq('M', how='end')
输出: Period('2007-12', 'M')
--------------------------------------------------------------------------------
把 TimeStamp 转变成 区间时间,
rng = pd.date_range('2000-01-01', periods=3, freq='M')
ts = pd.Series(np.random.randn(3), index=rng)
ts 输出: ts 中是某天的一个点时间
2000-01-31 -1.014323
2000-02-29 -0.180117
2000-03-31 1.407950
Freq: M, dtype: float64
ts.to_period() # freq 是月,所以变成了月的区间时间
输出:
2000-01 -1.014323
2000-02 -0.180117
2000-03 1.407950
Freq: M, dtype: float64
--------------------------------------------------------------------------------
# 还能指定 新的区间 'A' 表示年
ts.to_period('A')
输出:
2000 -1.014323
2000 -0.180117
2000 1.407950
Freq: A-DEC, dtype: float64 # 时间间隔变成年, 结束时间为每年的12月最后一天
--------------------------------------------------------------------------------
转来转去:
ts.to_period('A').to_timestamp(how='end') # 上面改变了间隔为 A-DEC, 所以这里是这样的。
2000-12-31 23:59:59.999999999 -1.014323
2000-12-31 23:59:59.999999999 -0.180117
2000-12-31 23:59:59.999999999 1.407950
dtype: float64
================================================================================
分享
收藏
点赞人
举报
文章标签
评论列表