Pandas 時間序列


# 導入相關庫 
import numpy as np 
import pandas as pd

在做金融領域方面的分析時,經常會對時間進行一系列的處理。Pandas 內部自帶了很多關於時間序列相關的工具,所以它非常適合處理時間序列。在處理時間序列的過程中,我們經常會去做以下一些任務:

  • 生成固定頻率日期和時間跨度的序列
  • 將時間序列整合或轉換為特定頻率
  • 基於各種非標准時間增量(例如,在一年的最后一個工作日之前的 5 個工作日)計算“相對”日期,或向前或向后“滾動”日期 

使用 Pandas 可以輕松完成以上任務

基礎概述

  下面列出了 Pandas中 和時間日期相關常用的類以及創建方法:

  Pandas 中關於時間序列最常見的類型就是時間戳( Timestamp )了,創建時間戳的方法有很多種,我們分別來看一看

時間戳(Timestamp)

pd.Timestamp(2019, 11, 7)   # Timestamp('2019-11-07 00:00:00')
pd.Timestamp("2019-11-7")   # Timestamp('2019-11-07 00:00:00')
pd.to_datetime("2019-11-7")  # Timestamp('2019-11-07 00:00:00')

  除了時間戳之外,另一個常見的結構是時間跨度( Period )

時間跨度(Period)

  freq 為頻率周期參數,D 為日,M 為月 

pd.Period("2019-11")   # Period('2019-11', 'M')
pd.Period("2019-11-7")   # Period('2019-11-07', 'D')
pd.Period("2019-11", freq="D")   # Period('2019-11-01', 'D')

基於時間的索引

  Timestamp 和 Period 可以是索引。將 Timestamp 和 Period 作為 Series 或 DataFrame 的索引后會自動強制轉為 DatetimeIndex 和 PeriodIndex

  Timestamp 作為索引

dates = [
  pd.Timestamp("2019-11-01"),
  pd.Timestamp("2019-11-02"),
  pd.Timestamp(
"2019-11-03"),
  pd.Timestamp("2019-11-04")
] ts
= pd.Series(data=["Tom", "Bob", "Mary", "James"], index=dates) ts """ 2018-05-01 Tom 2018-05-02 Bob 2018-05-03 Mary 2018-05-04 James dtype: object """ ts.index """ DatetimeIndex(['2018-05-01', '2018-05-02', '2018-05-03', '2018-05-04'], dtype='datetime64[ns]', freq=None) """

  Period 作為索引

periods = [
    pd.Period("2018-01"), 
    pd.Period("2018-02"), 
    pd.Period("2018-03"), 
    pd.Period("2018-4")
] 
ts = pd.Series(data=["Tom", "Bob", "Mary", "James"], index=periods) 
ts
"""
2018-01      Tom
2018-02      Bob
2018-03     Mary
2018-04    James
Freq: M, dtype: object
"""
ts.index 
"""
PeriodIndex(['2018-01', '2018-02', '2018-03', '2018-04'], dtype='period[M]', freq='M')
"""

轉換時間戳

  你可能會想到,我們經常要和文本數據(字符串)打交道,能否快速將文本數據轉為時間戳呢?答案是可以的,通過 to_datetime 能快速將字符串轉換為時間戳。當傳遞一個Series時,它會返 回一個Series(具有相同的索引),而類似列表的則轉換為 DatetimeIndex

to_datetime 將字符串轉換為時間戳

pd.to_datetime(pd.Series(["Jul 31, 2019", "2019-11-10", None])) 
"""
0   2019-07-31
1   2019-11-10
2          NaT
dtype: datetime64[ns]
"""

pd.to_datetime(["2008/8/28", "2008.9.25"])
"""
DatetimeIndex(['2008-08-28', '2008-09-25'], dtype='datetime64[ns]', freq=None)
"""

將 unix 時間轉為時間戳

pd.to_datetime([1349720105, 1349806505, 1349892905], unit="s")
"""
DatetimeIndex(['2012-10-08 18:15:05', '2012-10-09 18:15:05',
               '2012-10-10 18:15:05'],
              dtype='datetime64[ns]', freq=None)
"""

pd.to_datetime([1349720105100, 1349720105200, 1349720105300], unit="ms")
"""
DatetimeIndex(['2012-10-08 18:15:05.100000', '2012-10-08 18:15:05.200000',
               '2012-10-08 18:15:05.300000'],
              dtype='datetime64[ns]', freq=None)
"""

 

生成時間戳范圍

  有時候,我們可能想要生成某個范圍內的時間戳。例如,我想要生成 "2019-10-1" 這一天之后的8 天時間戳,如何完成呢?我們可以使用 date_range 和 bdate_range 來完成時間戳范圍的生成。

生成某個范圍內的時間戳

  date_range 默認使用的頻率是日歷日

  bdate_range 默認使用的頻率是營業日

pd.date_range("2019-10-1", periods=7) 
"""
DatetimeIndex(['2019-10-01', '2019-10-02', '2019-10-03', '2019-10-04',
               '2019-10-05', '2019-10-06', '2019-10-07'],
              dtype='datetime64[ns]', freq='D')
"""

pd.bdate_range("2019-10-1", periods=7) 
"""
DatetimeIndex(['2019-10-01', '2019-10-02', '2019-10-03', '2019-10-04',
               '2019-10-07', '2019-10-08', '2019-10-09'],
              dtype='datetime64[ns]', freq='B')
"""

按周來生成時間戳范圍

pd.date_range("2019-10-1", periods=7, freq="W")
"""
DatetimeIndex(['2019-10-06', '2019-10-13', '2019-10-20', '2019-10-27',
               '2019-11-03', '2019-11-10', '2019-11-17'],
              dtype='datetime64[ns]', freq='W-SUN')
"""

DatetimeIndex

  DatetimeIndex 的主要作用之一是用作 Pandas 對象的索引,使用它作為索引除了擁有普通索引對象的所有基本功能外,還擁有簡化頻率處理的高級時間序列方法

rng = pd.date_range("2019-10-1", periods=4, freq="W") 
ts = pd.Series(range(len(rng)), index=rng) 
ts
"""
2019-10-06    0
2019-10-13    1
2019-10-20    2
2019-10-27    3
Freq: W-SUN, dtype: int64
"""

通過日期訪問數據

ts["2019-10-20"]  # 2

通過日期區間訪問數據切片

ts["2019-10-13": "2019-10-20"]
"""
2019-10-13    1
2019-10-20    2
Freq: W-SUN, dtype: int64
"""

傳入年份

ts["2019"]

傳入年份和月份

ts["2019-10"]

datetime 進行索引

from datetime import datetime 
ts[datetime(2019, 10, 6) : datetime(2019, 10, 13)]

獲取年份

ts.index.year

獲取星期幾

ts.index.dayofweek

獲取一年中的第幾個星期

ts.index.weekofyear 

DateOffset 對象

  DateOffset 是做日期偏移的,它的參數與 dateutil.relativedelta 基 本相同,工作方式如下:

from pandas.tseries.offsets import *
d = pd.Timestamp("2019-10-06") 
d + DateOffset(weeks=2, days=5) 
"""
Timestamp('2019-10-25 00:00:00')
"""

  除了可以使用 DateOffset 完成上面的功能外,還可以使用偏移量實例來完成: 

from pandas.tseries.offsets import *
d = pd.Timestamp("2019-10-06") 
d + Week(2) + Day(5) 

與時間序列相關的方法

  在做時間序列相關的工作時,經常要對時間做一些移動/滯后、頻率轉換、采樣等相關操作。

移動時間序列 

  如果你想移動或滯后時間序列,你可以使用  shift  方法

ts.shift(2) 
"""
2019-10-06    NaN
2019-10-13    NaN
2019-10-20    0.0
2019-10-27    1.0
Freq: W-SUN, dtype: float64
"""

  可以看到,Series 所有的值都都移動了 2 個距離。如果不想移動值,而是移動日期索引,可以使 用  freq  參數,它可以接受一個  DateOffset  類或其他  timedelta  類對象或一個 offset 別名

ts.shift(2, freq=Day())
"""
2019-10-08    0
2019-10-15    1
2019-10-22    2
2019-10-29    3
Freq: W-TUE, dtype: int64
"""

  通過 tshift 同樣可以達到相同的效果: 

ts.tshift(2, freq=Day()) 

頻率轉換 

  頻率轉換可以使用 asfreq 函數來實現

# 將頻率由周轉為了天
ts.asfreq(Day()) 

  但是我們發現出現了缺失值,因此 Pandas 提供了 method 參數來填充缺失值。幾種不同的填充方法參考 Pandas 缺失值處理 中 fillna 介紹。 

ts.asfreq(Day(), method="pad")

重采樣

  resample 表示根據日期維度進行數據聚合,可以按照分鍾、小時、工作日、周、月、年等來作為日期維度

  這里我們以月來作為時間維度來進行聚合

# 求出每個月的數值之和
 ts.resample("1M").sum()

# 求出每個月的數值平均值 
ts.resample("1M").mean()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM