文章目錄
- 一、生成時(shí)間戳范圍
- 1. 指定值
- 2. 指定開(kāi)始日期并設(shè)置期間數(shù)
- 3. 頻率 freq
- 4. closed
- 二、Pandas 的時(shí)期函數(shù) Period()
- 三、時(shí)間序列 - 重采樣 resample
- 在開(kāi)始之前,我們先導(dǎo)入 numpy 和 pandas 庫(kù),同時(shí)導(dǎo)入 python 內(nèi)置的模塊。
import pandas as pd?
import numpy as np
?import time?
import datetime
一、生成時(shí)間戳范圍
- 有時(shí)候,我們可能想要生成某個(gè)范圍內(nèi)的時(shí)間戳。例如,我想要生成 “2018-6-26” 這一天之后的 8 天時(shí)間戳,我們可以使用
date_range
和 bdate_range
來(lái)完成時(shí)間戳范圍的生成。 - 我們可以通過(guò) date_range() 返回固定頻率的 DatetimeIndex。
- 其語(yǔ)法模板如下:
date_range(start=None, end=None, periods=None, freq=None, tz=None, normalize=False, name=None, closed=None, **kwargs)
- 他返回等距時(shí)間點(diǎn)的范圍(其中任意兩個(gè)相鄰點(diǎn)之間的差值由給定頻率指定),以便它們都滿(mǎn)足 start <[= ]x <[=] end,其中第一個(gè)和最后一個(gè)分別為。該范圍內(nèi)的第一個(gè)和最后一個(gè)時(shí)間點(diǎn)位于 freq 的邊界(如果以頻率字符串的形式給出)或?qū)?freq 有效。
- 其參數(shù)含義如下:
- start 表示生成日期的左邊界。
- end 表示生成日期的左邊界。
- periods 表示要生成的周期數(shù)。
- freq 表示頻率, default ‘D’ ,頻率字符串可以有倍數(shù),例如 ‘5H’。
- tz 表示時(shí)區(qū)用于返回本地化日期時(shí)間索引的時(shí)區(qū)名稱(chēng),例如 “Asia/Hong_Kong”。默認(rèn)情況下,生成的 DatetimeIndex 是時(shí)區(qū)初始索引。
- normalize: 默認(rèn) False, 在生成日期范圍之前,將開(kāi)始/結(jié)束日期標(biāo)準(zhǔn)化。
- name:默認(rèn) None 設(shè)置返回 DatetimeIndex name。
1. 指定值
- 默認(rèn)是包含開(kāi)始和結(jié)束時(shí)間,默認(rèn)頻率使用的 D(天)。
- 示例 1:我們生成從 20210101 到 20210108 之間以天為單位長(zhǎng)度的時(shí)間戳。
pd.date_range(start='1/1/2021', end='1/08/2021')
- 示例 2:我們生成 2010 年到 2011 年之間以天為單位長(zhǎng)度的時(shí)間戳。
pd.date_range(start='2010', end='2011')
2. 指定開(kāi)始日期并設(shè)置期間數(shù)
- 我們也可以指定開(kāi)始時(shí)間和中間經(jīng)過(guò)幾天。
pd.date_range(start='1/1/2018', periods=8)
- 我們也可以指定開(kāi)始、結(jié)束和期間,頻率就會(huì)自動(dòng)生成(線性間隔)。
- 例如,我們將開(kāi)始定為 20180424,結(jié)束定為 20180427,期間定為 3,那么他就會(huì)自動(dòng)以一天半為間隔進(jìn)行時(shí)間戳的生成。
pd.date_range(start='2018-04-24', end='2018-04-27', periods=3)
- 如果我們不定義開(kāi)始值,只定義結(jié)束值和期間,那么他會(huì)向前推導(dǎo)時(shí)間戳。
pd.date_range(end='2018-04-24', periods=4)
3. 頻率 freq
freq | 描述 |
---|
Y | 年 |
M | 月 |
D | 日(默認(rèn)) |
T(MIN) | 分鐘 |
S | 秒 |
L | 毫秒 |
U | 微妙 |
A-DEC | 每年指定月份的最后一個(gè)日歷日 |
W-MON | 指定每月的哪個(gè)星期開(kāi)始 |
WOM_2MON | 指定每個(gè)月的第幾個(gè)星期的星期幾開(kāi)始(這里是第二個(gè)星期的星期一) |
Q-DEC(Q-月) | 指定月為季度末,每個(gè)季度末最后一月的最后一個(gè)日歷日 |
B,(M,Q,A),S | 分別代表了工作日(以月為頻率,以季度為頻率,以年為頻率),最接近月 |
B | 工作日 |
- 其中,月和星期的縮寫(xiě)基本是英語(yǔ)的前三個(gè)字母大寫(xiě)為準(zhǔn)。
- 其中,Q-月只有三種情況:1-4-7-10,2-5-8-11,3-6-9-12。
- 例如,我們可以通過(guò) W-MON,從指定星期一開(kāi)始算起。
pd.date_range('2022/1/1','2022/2/1', freq = 'W-MON')
- 例如,我們可以通過(guò) WOM-2MON,從每月的第二個(gè)星期一開(kāi)始。
pd.date_range('2022/1/1','2022/5/1', freq = 'WOM-2MON')
- 我們可以只返回時(shí)間范圍內(nèi)的工作日。
pd.date_range('2022/1/1','2022/1/5', freq = 'B')
- 我們可以以小時(shí)為單位長(zhǎng)度返回時(shí)間戳。
pd.date_range('2022/1/1','2022/1/2', freq = 'H')
- 我們可以以分鐘為單位長(zhǎng)度返回時(shí)間戳。
pd.date_range('2022/1/1 12:00','2022/1/1 12:10', freq = 'T')
- 我們可以以秒、毫秒和微秒為單位長(zhǎng)度返回時(shí)間戳。
pd.date_range('2022/1/1 12:00:00','2022/1/1 12:00:10', freq = 'S')
pd.date_range('2022/1/1 12:00:00','2022/1/1 12:00:10', freq = 'L')
pd.date_range('2022/1/1 12:00:00','2022/1/1 12:00:10', freq = 'U')
- 我們可以通過(guò) M 返回每月的最后一個(gè)日歷日。
pd.date_range('2017','2018', freq = 'M')
- 我們可以通過(guò) Q-月,返回每個(gè)季度末最后一月的最后一個(gè)日歷日。
print(pd.date_range('2017','2020', freq = 'Q-DEC'))
- 我們可以通過(guò) A-月,返回每年指定月份的最后一個(gè)日歷日。
print(pd.date_range('2017','2020', freq = 'A-DEC'))
- 我們可以通過(guò) BM 返回每的最后一個(gè)工作日,BQ-月返回每個(gè)季度末最后一月的最后一個(gè)工作日,BA-月返回每年指定月份的最后一個(gè)工作日。
pd.date_range('2017','2018', freq = 'BM')
pd.date_range('2017','2020', freq = 'BQ-DEC')
pd.date_range('2017','2020', freq = 'BA-DEC')
- 我們可以通過(guò) pd.date_range() 指定時(shí)間頻率(下面以 7 天,2 小時(shí) 30 分鐘,2 月為例)。
print(pd.date_range('2017/1/1','2017/2/1', freq = '7D'))
print(pd.date_range('2017/1/1','2017/1/2', freq = '2h30min'))
print(pd.date_range('2017','2018', freq = '2M'))
4. closed
- closed 是覺(jué)得我們是否包含 start 值和 end 值,默認(rèn)情況下是兩個(gè)值都包含。
- 如果 closed 設(shè)置為 left,則表示不包含 end 值。
- 如果 closed 設(shè)置為 right,則表示不包含 start 值。
- 我們先生成初始數(shù)據(jù),便于后續(xù)的觀察。
pd.date_range(start='1/1/2021', end='1/08/2021')
- 我們將 closed 設(shè)置為 left。
pd.date_range(start='1/1/2021', end='1/08/2021',closed='left')
- 我們將 closed 設(shè)置為 right。
pd.date_range(start='1/1/2021', end='1/08/2021',closed='right')
- 我們可以通過(guò)
bdate_range(start=None, end=None, periods=None, freq='B')
語(yǔ)法返回固定頻率的 DatetimeIndex,默認(rèn)頻率為 B(工作日)。
pd.bdate_range(start='2022-01-01', end='2022-02-01')
二、Pandas 的時(shí)期函數(shù) Period()
- 我們可以直接使用 period() 輸出時(shí)期,他默認(rèn)是 A-DEC(每年指定月份的最后一個(gè)日歷日)。
p = pd.Period('2017')
p
Period('2017', 'A-DEC')
- 也可以對(duì)他的頻率進(jìn)行設(shè)置。
p = pd.Period('2017-1', freq = 'M')
print(p, type(p))
- (1) 可以通過(guò)加減整數(shù)可以實(shí)現(xiàn)對(duì) Period 的移動(dòng)(默認(rèn)是以月為單位進(jìn)行加減)。
print(p + 1)
print(p - 2)
- (2) 如果兩個(gè) Period 對(duì)象擁有相同頻率,則它們的差就是它們之間的單位數(shù)量。
p = pd.Period('2017-1', freq = 'M')
print(p, type(p))
pd.Period('2018', freq='M') - p
- (3) period_range 函數(shù)可用于創(chuàng)建規(guī)則的時(shí)期范圍。
rng = pd.period_range('2021-1-1', '2021-6-1')
rng
- (4) PeriodIndex 類(lèi)的構(gòu)造函數(shù)允許直接使用一組字符串表示一段時(shí)期。
- 這里需要注意的是,我們必須指定 freq。
values = ['200103', '200104', '200105']
index = pd.PeriodIndex(values, freq='M')
index
- (5) 時(shí)期的頻率轉(zhuǎn)換 asfreq。
- freq 當(dāng)中的 A-月表示每年指定月份的最后一個(gè)日歷日。
p = pd.Period('2021', freq='A-DEC')
p
- 我們可以使用 asfreq 將時(shí)期的頻率進(jìn)行轉(zhuǎn)換 M(月),通過(guò)設(shè)置 how 的參數(shù)為 start 或者 end 決定是起始還是結(jié)束。
p.asfreq('M')
- 我們將 how 設(shè)置為 start,也可寫(xiě) how = ‘s’。
p.asfreq('M', how="start")
- 我們將 how 設(shè)置為 end,也可寫(xiě) how = ‘e’。
p.asfreq('M', how="end")
- 也可以將 asfreq 轉(zhuǎn)換為 s(秒)。
p.asfreq('H',how="s")
- (6) 對(duì)于 PeriodIndex 或 TimeSeries 的頻率轉(zhuǎn)換方式相同。
- 示例 1:
rng = pd.period_range('2006', '2009', freq='A-DEC')
rng
ts = pd.Series(np.random.rand(len(rng)), rng)
ts
ts.asfreq('M', how='s')
- 示例 5:對(duì) asfreq 的 how 參數(shù)不設(shè)置就默認(rèn)為 end。
ts.asfreq('M')
ts2 = pd.Series(np.random.rand(len(rng)), index = rng.asfreq('D', how = 'start'))
ts2
- (7) 時(shí)間戳與時(shí)期之間的轉(zhuǎn)換:pd.to_period()、pd.to_timestamp()。
- 我們通過(guò)生成一個(gè)從 20170101 開(kāi)始,以月為間隔生成 10 個(gè)數(shù)據(jù)和從 2017 到 2018 以月為間隔的兩個(gè)初始數(shù)據(jù),便于后續(xù)的操作觀察。
rng = pd.date_range('2017/1/1', periods = 10, freq = 'M')
prng = pd.period_range('2017','2018', freq = 'M')
print(rng)
print(prng)
- 通過(guò)隨機(jī)函數(shù)生成與 rng 長(zhǎng)度個(gè)數(shù)相同的數(shù)據(jù),并將標(biāo)簽設(shè)置為 rng。
ts1 = pd.Series(np.random.rand(len(rng)), index = rng)
ts1
- 我們可以將每月最后一日,轉(zhuǎn)化為每月。to_period()參數(shù)為空, 推斷每日頻率(head 表示讀取前五個(gè)數(shù)據(jù))。
ts1.to_period().head()
- 以和 rng 相同的方式通過(guò)隨機(jī)函數(shù)生成 prng,并通過(guò) head 讀取他的前五個(gè)數(shù)據(jù)。
ts2 = pd.Series(np.random.rand(len(prng)), index = prng)
print(ts2.head())?
print(ts2.to_timestamp().head())
三、時(shí)間序列 - 重采樣 resample
- Pandas 中的 resample 函數(shù),被叫做重新采樣,是對(duì)原樣本重新處理的一個(gè)方法,是一個(gè)對(duì)常規(guī)時(shí)間序列數(shù)據(jù)重新采樣和頻率轉(zhuǎn)換的便捷的方法。
- 他的作用是重新取樣時(shí)間序列數(shù)據(jù)。
- 對(duì)象必須具有類(lèi)似 datetime 的索引(DatetimeIndex、PeriodIndex 或 TimedeltaIndex),或?qū)㈩?lèi)似 datetime 的值傳遞給 on 或 level 關(guān)鍵字。
- 其語(yǔ)法模板如下:
DataFrame.resample(rule, closed=None, label=None, level=None)
- 其部分參數(shù)含義如下:
- rule 表示目標(biāo)轉(zhuǎn)換的偏移量字符串或?qū)ο蟆?/li>
- closed 表示在降采樣時(shí),各時(shí)間段的哪一段是閉合的,‘right’ 或 ‘left’,默認(rèn)‘right’。
- label 表示在降采樣時(shí),如何設(shè)置聚合值的標(biāo)簽,例如,9:30-9:35會(huì)被標(biāo)記成9:30還是9:35,默認(rèn)是 9:35。
- 我們可以生成從 20170101 開(kāi)始的 12 個(gè)數(shù),并以他為標(biāo)簽,通過(guò)函數(shù)生成對(duì)應(yīng)的數(shù)據(jù),
rng = pd.date_range('20170101', periods = 12)
ts = pd.Series(np.arange(12), index = rng)
print(ts)
Freq: D, dtype: int32
- 我們將序列下采樣到 5 天的數(shù)據(jù)箱中(以 5 天為時(shí)間單位),并將放入數(shù)據(jù)箱的時(shí)間戳的值相加。
ts.resample('5D').sum()
- 我們就會(huì)得到一個(gè)新的聚合后的 Series,聚合方式為求和,當(dāng)然,我們也可以生成其他的聚合方式。
print(ts.resample('5D').mean(),'→ 求平均值\n')
print(ts.resample('5D').max(),'→ 求最大值\n')
print(ts.resample('5D').min(),'→ 求最小值\n')
print(ts.resample('5D').median(),'→ 求中值\n')
print(ts.resample('5D').first(),'→ 返回第一個(gè)值\n')
print(ts.resample('5D').last(),'→ 返回最后一個(gè)值\n')
print(ts.resample('5D').ohlc(),'→ OHLC重采樣\n')
- 知識(shí)點(diǎn)補(bǔ)充:
- OHLC 是金融領(lǐng)域的時(shí)間序列聚合方式,包括 open開(kāi)盤(pán)、high 最大值、low 最小值、close 收盤(pán)。
- closed 表示各時(shí)間段哪一端是閉合(即包含)的,默認(rèn)是右端閉合。
- 詳解:這里 values 為 0-11,按照 5D 重采樣,可以分為以下三類(lèi) [1,2,3,4,5],[6,7,8,9,10],[11,12]。
- left 表示指定間隔左邊為結(jié)束,就是 [1,2,3,4,5],[6,7,8,9,10],[11,12]。
- right 表示指定間隔右邊為結(jié)束,就是 [1],[2,3,4,5,6],[7,8,9,10,11],[12]。
- 我們將系列降采樣到 5 天的箱中,但關(guān)閉箱間隔的左側(cè)。
print(ts.resample('5D', closed = 'left').sum(), '→ left\n')
- 我們將系列降采樣到 5 天的箱中,但關(guān)閉箱間隔的右側(cè)。
print(ts.resample('5D', closed = 'right').sum(), '→ right\n')