《利用python進行資料分析》 第10章 時間序列
阿新 • • 發佈:2019-01-22
第十章、時間序列
- 時間戳timestamp:特定的時刻
- 固定時期period:2017年1月或2017年全年
- 時間間隔interval:時期是間隔的特例
- 實驗或過程時間:每一個時間點都是對特定起始實踐的一個獨立那個。例如,從放入烤箱起,每秒鐘餅乾的直徑。
10.1 日期和時間資料型別及工具
datetime模組:from datetime import datetime
datetime是指以毫秒形式儲存日期和時間的。
# datetime now = datetime.now() now out: datetime.datetime(2012,8,4,17,9,21,832092) now.year,now.month,now.day out: (2012,8,4) # timedelta物件表示兩個datetime之間的時間差 delta = datetime(2011,1,7) - datetime(2008,6,24,8,15) delta.days out: 926 # 用一個datetime加上或減去一個timedelta start = datetime(2011,1,7) start + timedelta(12) # 預設是天? out: datetime.datetime(2011,1,19,0,0)
字串和datetime的互相轉換
stamp = datetime(2011,1,3) # datetime-str:str函式 str(stamp) # datetime-str:strftime函式 # ?str from time? stamp.strftime('%Y%m%d%H%M%S') # 年月日時分秒 # str-datetime:datetime.strptime函式 # ?str parse time? datestrs = '7/6/2018' date = datetime.strptime(datestrs,'%m%d%Y') # datetime.strptime還要編寫格式,直接用第三方庫 from dateutil.parser import parse parse('2011-01-01') # 在國際通用時間裡,日經常在月的前面,可以用過dayfirst=True調節 parse('6/12/2011',dayfirst=True) # 處理整組的時間日期 datestrs = ['7/6/2011','8/6/2011'] pd.to_datetime(datestrs)
另:
- %w:星期幾
- %W:第幾周
- …
10.2 時間序列基礎
TimeSeires
TimeSeries是Series的一個子類。因此使用方法和Series一致。以下是獨遊的:
longer_ts = Series(np.random.randn(1000),index=pd.date_range('1/1/2000',periods=1000))
# 按年索引
longer_ts['2001']
# 切片不能直接寫年份,要規則的書寫
longer_ts[datetime(2011,1,7)]
帶重複索引的時間序列
# 判斷是否重複 dup_ts.index.is_unique # is_unique為False的時候,索引=切片 # 可以進行聚合運算 dup_ts.groupby(level=0).mean()
10.3 日期的範圍、頻率以及移動
Pandas 中的時間序列一般被認為是不規則的,也就是說,它們沒有固定的頻率。對於大部分應用程式而言,這是無所謂的。但是,它常常需要以某種相對固定的頻率進行分析,比如每日、每月、每 15 分鐘等(這樣自然會在時間序列中引人缺失值)。幸運的是,pandas 有一整套標準時間序列頻率以及用於重取樣、頻率推斷、生成固定頻率日期範圍的工具。例如,我們可以將之前那個時間序列轉換為一個具有固定頻率(每日)的時間序列,只需呼叫 resample 即可:
ts
out:
2011-01-02 xxx
2011-01-04 xxx
2011-01-11 xxx
2011-01-13 xxx
2011-01-15 xxx
ts.resample('D')
out:
2011-01-02 xxx
2011-01-03 xxx
2011-01-04 xxx
2011-01-05 xxx
2011-01-06 xxx
2011-01-07 xxx
2011-01-08 xxx
2011-01-09 xxx
2011-01-10 xxx
2011-01-11 xxx
2011-01-12 xxx
2011-01-13 xxx
2011-01-14 xxx
2011-01-15 xxx
生成日期範圍 date_range()
預設保留起始和結束的時間戳(如果有的話)
# 給定起止時間,生成時間序列
pd.date_range('7/6/2012','6/1/2012')
# 只給開始時間和長度
pd.date_range(start='7/6/2012',period=20)
# 只給終止時間和長度
pd.date_range(end='7/6/2012',period=20)
# 指定頻率,預設為D,可以指定businuss end of month “BM”
pd.date_range('7/6/2012','6/1/2012',freq='BM')
# freq會在下一節中說
# 產生規範化到午夜的時間戳
pd.date_range(start='7/6/2012 12:56:22',period=20,normalize=True)
頻率和日期偏移量
from pandas.tseries.offsets import Hour,Minute
主要用在date_range中的freq裡。
hour = Hour()
hour
out:
<1 Hour>
four_hour = Hour(4)
four_hour
out:
<4 Hours>
# 以下是簡化版本
4H
# 加減乘除
Hour(2) + Minute(30)
out:
<150 Minute>
# 傳入字串
pd.date_range('1/1/2000',periods=10,freq='1h30min')
- D:每日曆日
- B:每工作日
- H:每小時
- T或min:每分鐘
- S:每秒
- M:每月最後一個日曆日
- BM:每月最後一個工作日
- MS:每月第一個日曆日
- BMS:每月第一個工作日
- 其他
移動(超前和滯後)資料 shift()
可以用於計算一個時間序列或多個時間序列的百分比的變化
# 後挪2個
ts.shift(2)
# 前挪2個
ts.shift(-2)
10.4 時區處理
嚶嚶嚶
10.5 時期及其算術運算
時期就是特殊的時間段
時期的頻率轉換
# 建立一個時期,表示2017.01.01-2017.12.31之間的整段時間
pd.Period(2007,freq='A-DEC')
# 建立一個時期序列
pd.Period_range('1/1/2000','6/30/2000',freq='M')
# 改變時期頻率
p = pd.Period('2008',freq='A-DEC')
p.asfreq('M',how='start')
out:
Period('2007-01','M')
按季度計算的時期頻率
pd.asfreq('下圖裡面的',how=?)
將Timestamp轉換為Period(及其反向過程)
# 將timestamp轉換為period
pts = ts.to_period()
# 將period轉換為timestamp
ts = pts.to_timestamp(how='end')
通過陣列建立PeriodIndex
# 將兩個陣列以及一個頻率傳入構造器中,可以將兩個陣列的時間合併,如年份+季度
index = pd.PeriodIndex(year=data.year,quarter=data.quarter,freq='A-DEC')
data.index = index
data
out:
1959Q1 x
1959Q2 x
...
10.6 重取樣及頻率轉換
重取樣 resempling
高頻率——>低頻率:降取樣,如日到月
低頻率——>高頻率:升取樣,如月到日
resample函式的引數:
- freq:重取樣頻率的字串
- how=‘mean’:聚合函式的名稱
- axis=0:重取樣的軸
- fill_method=None:升取樣的插值方法
- closed=‘right’:哪端閉合
- …
降取樣
rng = pd.data_range('1/1/2000',period=12,freq='T')
ts = Series(np.arange(12),index=rng)
# 1分到5分,sum,預設closed為right,見下圖
ts.resample('5min',how='sum')
升取樣與插值
# 插值方法和fillna與reindex是一樣的
frame.resample('D',fill_method=?)
# 需要指定哪段放原來的值,預設為end
frame.resample('Q-DEC',fill_method='ffill',convention='start')
10.7 時間序列繪圖
略
10.8 移動視窗函式
略
10.9 效能和記憶體上使用方面的注意
略