Pandas處理時序數據(初學者必會)!

2021-03-02 Datawhale

↑↑↑關注後"星標"Datawhale

每日乾貨 & 每月組隊學習,不錯過

作者:耿遠昊,Datawhale成員,華東師範大學

時序數據是指時間序列數據。時間序列數據是同一統一指標按時間順序記錄的數據列。在同一數據列中的各個數據必須是同口徑的,要求具有可比性。時序數據可以是時期數,也可以時點數。時間序列分析的目的是通過找出樣本內時間序列的統計特性和發展規律性,構建時間序列模型,進行樣本外預測。

本文目錄

    1. 時序的創建

        1.1. 四類時間變量

        1.2. 時間點的創建

        1.3. DataOffset對象

    2. 時序的索引及屬性

        2.1. 索引切片

        2.2. 子集索引

        2.3. 時間點的屬性

    3. 重採樣

        3.1. resample對象的基本操作

        3.2. 採樣聚合

        3.3. 採樣組的迭代

    4. 窗口函數

        4.1. Rolling

        4.2. Expanding

    5. 問題及練習

        5.1. 問題

import pandas as pdimport numpy as np

一、時序的創建1.1. 四類時間變量現在理解可能關於③和④有些困惑,後面會作出一些說明

1.2. 時間點的創建(a)to_datetime方法Pandas在時間點建立的輸入格式規定上給了很大的自由度,下面的語句都能正確建立同一時間點
pd.to_datetime('2020.1.1')pd.to_datetime('2020 1.1')pd.to_datetime('2020 1 1')pd.to_datetime('2020 1-1')pd.to_datetime('2020-1 1')pd.to_datetime('2020-1-1')pd.to_datetime('2020/1/1')pd.to_datetime('1.1.2020')pd.to_datetime('1.1 2020')pd.to_datetime('1 1 2020')pd.to_datetime('1 1-2020')pd.to_datetime('1-1 2020')pd.to_datetime('1-1-2020')pd.to_datetime('1/1/2020')pd.to_datetime('20200101')pd.to_datetime('2020.0101')

Timestamp('2020-01-01 00:00:00')

下面的語句都會報錯
#pd.to_datetime('2020\\1\\1')#pd.to_datetime('2020`1`1')#pd.to_datetime('2020.1 1')#pd.to_datetime('1 1.2020')

此時可利用format參數強制匹配
pd.to_datetime('2020\\1\\1',format='%Y\\%m\\%d')pd.to_datetime('2020`1`1',format='%Y`%m`%d')pd.to_datetime('2020.1 1',format='%Y.%m %d')pd.to_datetime('1 1.2020',format='%d %m.%Y')

Timestamp('2020-01-01 00:00:00')

同時,使用列表可以將其轉為時間點索引
pd.Series(range(2),index=pd.to_datetime(['2020/1/1','2020/1/2']))

type(pd.to_datetime(['2020/1/1','2020/1/2']))

pandas.core.indexes.datetimes.DatetimeIndex

對於DataFrame而言,如果列已經按照時間順序排好,則利用to_datetime可自動轉換
df = pd.DataFrame({'year': [2020, 2020],'month': [1, 1], 'day': [1, 2]})pd.to_datetime(df)

(b)時間精度與範圍限制事實上,Timestamp的精度遠遠不止day,可以最小到納秒ns
pd.to_datetime('2020/1/1 00:00:00.123456789')

Timestamp('2020-01-01 00:00:00.123456789')

同時,它帶來範圍的代價就是只有大約584年的時間點是可用的

Timestamp('1677-09-21 00:12:43.145225')

Timestamp('2262-04-11 23:47:16.854775807')

(c)date_range方法一般來說,start/end/periods(時間點個數)/freq(間隔方法)是該方法最重要的參數,給定了其中的3個,剩下的一個就會被確定
pd.date_range(start='2020/1/1',end='2020/1/10',periods=3)

pd.date_range(start='2020/1/1',end='2020/1/10',freq='D')

pd.date_range(start='2020/1/1',periods=3,freq='D')

pd.date_range(end='2020/1/3',periods=3,freq='D')

其中freq參數有許多選項,下面將常用部分羅列如下,更多選項可看這裡
pd.date_range(start='2020/1/1',periods=3,freq='T')

pd.date_range(start='2020/1/1',periods=3,freq='M')

pd.date_range(start='2020/1/1',periods=3,freq='BYS')

bdate_range是一個類似與date_range的方法,特點在於可以在自帶的工作日間隔設置上,再選擇weekmask參數和holidays參數它的freq中有一個特殊的'C'/'CBM'/'CBMS'選項,表示定製,需要聯合weekmask參數和holidays參數使用例如現在需要將工作日中的周一、周二、周五3天保留,並將部分holidays剔除

weekmask = 'Mon Tue Fri'holidays = [pd.Timestamp('2020/1/%s'%i) for i in range(7,13)]pd.bdate_range(start='2020-1-1',end='2020-1-15',freq='C',weekmask=weekmask,holidays=holidays)

1.3. DateOffset對象
(a)DataOffset與Timedelta的區別Timedelta絕對時間差的特點指無論是冬令時還是夏令時,增減1day都只計算24小時DataOffset相對時間差指,無論一天是23\24\25小時,增減1day都與當天相同的時間保持一致例如,英國當地時間 2020年03月29日,01:00:00 時鐘向前調整 1 小時 變為 2020年03月29日,02:00:00,開始夏令時
ts = pd.Timestamp('2020-3-29 01:00:00', tz='Europe/Helsinki')ts + pd.Timedelta(days=1)

Timestamp('2020-03-30 02:00:00+0300', tz='Europe/Helsinki')

ts + pd.DateOffset(days=1)

Timestamp('2020-03-30 01:00:00+0300', tz='Europe/Helsinki')

這似乎有些令人頭大,但只要把tz(time zone)去除就可以不用管它了,兩者保持一致,除非要使用到時區變換
ts = pd.Timestamp('2020-3-29 01:00:00')ts + pd.Timedelta(days=1)

Timestamp('2020-03-30 01:00:00')

ts + pd.DateOffset(days=1)

Timestamp('2020-03-30 01:00:00')

(b)增減一段時間DateOffset的可選參數包括years/months/weeks/days/hours/minutes/seconds
pd.Timestamp('2020-01-01') + pd.DateOffset(minutes=20) - pd.DateOffset(weeks=2)

Timestamp('2019-12-18 00:20:00')

(c)各類常用offset對象
pd.Timestamp('2020-01-01') + pd.offsets.Week(2)

Timestamp('2020-01-15 00:00:00')

pd.Timestamp('2020-01-01') + pd.offsets.BQuarterBegin(1)

Timestamp('2020-03-02 00:00:00')

(d)序列的offset操作利用apply函數

pd.Series(pd.offsets.BYearBegin(3).apply(i) for i in pd.date_range('20200101',periods=3,freq='Y'))

直接使用對象加減
pd.date_range('20200101',periods=3,freq='Y') + pd.offsets.BYearBegin(3)

定製offset,可以指定weekmask和holidays參數(思考為什麼三個都是一個值)
pd.Series(pd.offsets.CDay(3,weekmask='Wed Fri',holidays='2020010').apply(i)                                  for i in pd.date_range('20200105',periods=3,freq='D'))

二、時序的索引及屬性2.1. 索引切片這一部分幾乎與第二章的規則完全一致
rng = pd.date_range('2020','2021', freq='W')ts = pd.Series(np.random.randn(len(rng)), index=rng)ts.head()

-0.47982974619679947

合法字符自動轉換為時間點
ts['2020-01-26':'20200726'].head()

2.2. 子集索引

支持混合形態索引
ts['2011-1':'20200726'].head()

2.3. 時間點的屬性採用dt對象可以輕鬆獲得關於時間的信息
pd.Series(ts.index).dt.week.head()

pd.Series(ts.index).dt.day.head()

利用strftime可重新修改時間格式
pd.Series(ts.index).dt.strftime('%Y-間隔1-%m-間隔2-%d').head()

對於datetime對象可以直接通過屬性獲取信息
pd.date_range('2020','2021', freq='W').month

pd.date_range('2020','2021', freq='W').weekday

三、重採樣所謂重採樣,就是指resample函數,它可以看做時序版本的groupby函數3.1. resample對象的基本操作採樣頻率一般設置為上面提到的offset字符
df_r = pd.DataFrame(np.random.randn(1000, 3),index=pd.date_range('1/1/2020', freq='S', periods=1000),                  columns=['A', 'B', 'C'])

r = df_r.resample('3min')r

df_r2 = pd.DataFrame(np.random.randn(200, 3),index=pd.date_range('1/1/2020', freq='D', periods=200),                  columns=['A', 'B', 'C'])r = df_r2.resample('CBMS')r.sum()

3.2. 採樣聚合

r['A'].agg([np.sum, np.mean, np.std])

類似地,可以使用函數lambda表達式

r.agg({'A': np.sum,'B': lambda x: max(x)-min(x)})


3.3. 採樣組的迭代

採樣組的迭代和groupby迭代完全類似,對於每一個組都可以分別做相應操作
small = pd.Series(range(6),index=pd.to_datetime(['2020-01-01 00:00:00', '2020-01-01 00:30:00'                                                 , '2020-01-01 00:31:00','2020-01-01 01:00:00'                                                 ,'2020-01-01 03:00:00','2020-01-01 03:05:00']))resampled = small.resample('H')for name, group in resampled:    print("Group: ", name)    print("-" * 27)    print(group, end="\n\n")

四、窗口函數下面主要介紹pandas中兩類主要的窗口(window)函數:rolling/expanding
s = pd.Series(np.random.randn(1000),index=pd.date_range('1/1/2020', periods=1000))s.head()

4.1. Rolling(a)常用聚合所謂rolling方法,就是規定一個窗口,它和groupby對象一樣,本身不會進行操作,需要配合聚合函數才能計算結果

Rolling [window=50,center=False,axis=0]

s.rolling(window=50).mean()

min_periods參數是指需要的非缺失數據點數量閥值
s.rolling(window=50,min_periods=3).mean().head()

count/sum/mean/median/min/max/std/var/skew/kurt/quantile/cov/corr都是常用的聚合函數。(b)rolling的apply聚合使用apply聚合時,只需記住傳入的是window大小的Series,輸出的必須是標量即可,比如如下計算變異係數
s.rolling(window=50,min_periods=3).apply(lambda x:x.std()/x.mean()).head()

(c)基於時間的rolling
s.rolling('15D').mean().head()

可選closed='right'(默認)\'left'\'both'\'neither'參數,決定端點的包含情況
s.rolling('15D', closed='right').sum().head()

4.2. Expanding(a)expanding函數普通的expanding函數等價與rolling(window=len(s),min_periods=1),是對序列的累計計算
s.rolling(window=len(s),min_periods=1).sum().head()

s.expanding().sum().head()

apply方法也是同樣可用的
s.expanding().apply(lambda x:sum(x)).head()

(b)幾個特別的Expanding類型函數cumsum/cumprod/cummax/cummin都是特殊expanding累計計算方法

shift/diff/pct_change都是涉及到了元素關係① shift是指序列索引不變,但值向後移動② diff是指前後元素的差,period參數表示間隔,默認為1,並且可以為負③ pct_change是值前後元素的變化百分比,period參數與diff類似

五、問題與練習

5.1. 問題

【問題一】 如何對date_range進行批量加幀操作或對某一時間段加大時間戳密度?

【問題二】 如何批量增加TimeStamp的精度?【問題三】 對於超出處理時間的時間點,是否真的完全沒有處理方法?

【問題四】 給定一組非連續的日期,怎麼快速找出位於其最大日期和最小日期之間,且沒有出現在該組日期中的日期?

5.2. 練習

【練習一】 現有一份關於某超市牛奶銷售額的時間序列數據,請完成下列問題:

(a)銷售額出現最大值的是星期幾?(提示:利用dayofweek函數)

(b)計算除去春節、國慶、五一節假日的月度銷售總額

(c)按季度計算周末(周六和周日)的銷量總額

(d)從最後一天開始算起,跳過周六和周一,以5天為一個時間單位向前計算銷售總和

(e)假設現在發現數據有誤,所有同一周裡的周一與周五的銷售額記錄顛倒了,請計算2018年中每月第一個周一的銷售額(如果該周沒有周一或周五的記錄就保持不動)

【練習二】 繼續使用上一題的數據,請完成下列問題:

(a)以50天為窗口計算滑窗均值和滑窗最大值(min_periods設為1)

(b)現在有如下規則:若當天銷售額超過向前5天的均值,則記為1,否則記為0,請給出2018年相應的計算結果

(c)將(c)中的「向前5天」改為「向前非周末5天」,請再次計算結果

本文電子版 後臺回復 時序數據 獲取

「竟然學習完了,給自己點個

相關焦點

  • 使用Pandas進行數據處理
    引言我們將深入講解pandas庫在數據處理階段的功能數據處理又可以細分為三個階段,我們將通過例子詳細講解各個階段都會涉及哪些操作,以及如何充分利用pandas庫提供的函數來完成這些操作。數據處理的三個階段為:數據準備、數據轉換和數據聚合。數據準備開始處理數據工作之前,需要先行準備好數據,把數據組裝成便於用pandas庫的各種工具處理的數據結構。
  • 使用Pandas的resample函數處理時間序列數據的技巧
    時間序列數據在數據科學項目中很常見。
  • Python數據處理庫pandas入門教程
    在這種情況下,我們可以通過指定分隔符的方式來讀取這個文件,像這樣:實際上,read_csv支持非常多的參數用來調整讀取的參數,如下表所示:詳細的read_csv函數說明請參見這裡:pandas.read_csv處理無效值現實世界並非完美,我們讀取到的數據常常會帶有一些無效值。
  • 使用Pandas數據處理與分析
    前言:這是關於個人關於對pandas可以進行的數據處理和數據分析的見解的初版,其中肯定不乏一些錯誤之處,希望大家能多多指正。但是,在一般的數據處理分析中,往往自我生成數據情況較少,更多的是導入數據。pandas提供了一些用於將表格型數據讀取為DataFrame對象的函數。
  • Pandas對文本數據處理
    在處理數據的時候,對數值型的數據處理還是比較方便的,但是有時候數值型數據出現問題後就會比較頭痛了,因為文本數據的排列組合可是有很多很多的,今天我們就學習一下如何對文本數據進行處理,這樣我們接下來在工作中遇到了這些情況就可以少掉一下頭髮啦。
  • pandas讀取表格後的常用數據處理操作
    pandas讀取表格後的一些常用數據處理操作。這篇文章其實來源於自己的數據挖掘課程作業,通過完成老師布置的作業,感覺對於使用python中的pandas模塊讀取表格數據進行操作有了更深層的認識,這裡做一個整理總結。
  • 用pandas處理時間格式數據
    本文2023字,預計閱讀需10分鐘;我們在處理時間相關的數據時有很多庫可以用,最常用的還是內置的datetime、time這兩個。
  • 關於Pandas數據處理你不知道的技巧!
    旗下高端量化雲平臺當我們參加一些比賽時,我們可能要花費大量時間來處理數據。本文將由淺到深,為大家講解關於Pandas在數據清理和處理的一些技巧!,因為它不像Boston房價數據(Kaggle最經典的題目)集那樣處理得很好。
  • 數據處理技巧 | 帶你了解Pandas.groupby() 常用數據處理方法
    今天我們繼續推出一篇數據處理常用的操作技能匯總:靈活使用pandas.groupby()函數,實現數據的高效率處理,主要內容如下:pandas.groupby()三大主要操作介紹說到使用Python進行數據處理分析,那就不得不提其優秀的數據分析庫-Pandas,
  • Python數學建模技巧之pandas數據處理
    最常見的庫有進行矩陣運算的Numpy、進行數據處理的pandas、進行科學計算的Scipy、進行圖形繪製及科學可視化的matplotlib、進行符號計算的Sympy以及方便進行機器學習任務的Sklearn。由於今年美賽官方公告中稱,將會提前在賽題公布之前就提供下載C題數據集的方式。
  • 數據科學 | pandas數據導入與導出
    當我們開始著手做一個數據分析項目時,選擇和導入數據集是第一個步驟,而導出數據雖然非必需,但有時候我們也需要保存處理或者分析後的結果,方便下次使用。在pandas中,它已經為我們提供了很多不同格式數據的導入和導出方法,下面這篇文章將具體介紹一些較為常用的方法,包括excel、csv文件以及資料庫的導入導出等。數據導入和導出是pandas中很基礎且重要的一個部分。
  • 思考python數據分析工具pandas-1簡介
    介紹我們生活在一個充滿數據的世界裡。事實上,數據如此之多,幾乎不可能全部理解。我們比以往任何時候都更加依賴計算機來幫助我們理解這些海量的信息。無論是通過搜尋引擎進行數據發現,還是通過圖形用戶界面進行展示,或是通過算法進行聚合,我們都會使用軟體來處理、提取並以對我們有意義的方式呈現數據。"pandas "已經成為一個越來越受歡迎的處理大數據集的軟體包。
  • pandas | 使用pandas進行數據處理——DataFrame篇
    今天是pandas數據處理專題的第二篇文章,我們一起來聊聊pandas當中最重要的數據結構——DataFrame。並且為我們提供了許多表級別數據處理以及批量數據處理的接口,大大降低了數據處理的難度。雖然DataFrame可以近似看成是Series組合成的dict,但實際上它作為一個單獨的數據結構,也擁有許多自己的api,支持許多花式的操作,是我們處理數據強有力的工具。
  • pandas+PyQt5輕鬆製作數據處理工具
    作者:才哥由於在工作中需要處理很多日誌文件數據,這些數據並不存在於資料庫,而是以每日1個單文件的形式存在,為了讓我們在日常數據處理中更方便的進行一些基礎的數據合併、清洗篩選以及簡單的分組或數據透視處理,結合PyQt5與pandas庫,製作了一個簡單的數據處理可視化工具。
  • Python數據分析利器,Pandas入門介紹,幫你便捷高效處理複雜數據
    關於Python的數據分析,當我們遇到的數據量小、數據結構簡單時,可以通過字典、列表等Python常見的數據結構來處理。但是當我們面對的大量數據以及複雜數據的局面時,就需要用一些專門用於數據分析的擴展庫來處理數據了。今天給大家介紹一個Python裡專門用來做數據分析和處理的擴展庫。
  • 時序資料庫入門系列: 時序數據的查詢
    儘管時序數據的查詢類型或者場景多種多樣,但時序資料庫的查詢類型,整體上來說主要分成原始數據查詢、聚合數據查詢等兩種類型。原始數據查詢,顧名思義,就是查詢原始數據,將寫入的數據原封不動的查詢出來。由於查詢結果粒度太細,當時間範圍較大時,結果集通常較大,業務處理起來比較困難,且較難發現蘊含在結果集中的規律性和趨勢性。
  • Python數據分析之pandas數據讀寫
    引言我們現在已經基本熟悉了pandas庫以及它所提供的用於數據分析的基礎功能,也知道了DataFrame和Series是這個庫的核心,數據處理、計算和分析都是圍繞他們展開的。本節將學習pandas從多種存儲媒介(比如文件和資料庫)讀取數據的工具,還將學到直接將不同的數據結構寫入不同格式文件的方法,而無需過多考慮所使用的技術。本節的主要內容為pandas的多種I/O API函數,它們為大多數常用格式的數據作為DataFrame對象進行讀寫提供了很大便利。
  • 玩轉數據處理120題|Pandas&R
    和我一起玩Python本文精心挑選在數據處理中常見的120種操作並整理成習題發布。
  • Pandas常用的數據處理方法
    >Pandas中合併數據集有多種方式,這裡我們來逐一介紹1.1 資料庫風格合併資料庫風格的合併指根據索引或某一列的值是否相等進行合併的方式,在pandas中,這種合併使用merge以及join函數實現。
  • 數據處理 | pandas入門專題——離散化與one-hot
    今天是pandas數據處理專題第7篇文章,可以點擊上方專輯查看往期文章。假設某一維是收入,那麼它對應的係數顯然必須非常非常小,因為樣本當中有馬雲這種頂級大佬的收入存在,也就是說為了擬合這樣的極端數據,模型被帶跑偏了。這種情況非常多,因為現實生活當中很多數據的分布是非常不均勻的。