數據科學(十一)
時間日期
- 時間戳 tiimestamp:固定的時刻 -> pd.Timestamp
- 固定時期 period:比如 2016年3月份,再如2015年銷售額 -> pd.Period
- 時間間隔 interval:由起始時間和結束時間來表示,固定時期是時間間隔的一個特殊
時間日期在 Pandas 裏的作用
- 分析金融數據,如股票交易數據
- 分析服務器日誌
python 標準庫裏提供了時間日期的處理。這個是時間日期的基礎。
時間差
兩個datetime相減
字符串和 datetime 轉換
date = datetime(2016, 3, 20, 8, 30)
date.strftime(’%Y-%m-%d %H:%M:%S’)
datetime.strptime(‘2016-03-20 09:30’, ‘%Y-%m-%d %H:%M’)
Pandas 裏的時間序列
Pandas 裏使用 Timestamp 來表達時間
生成日期範圍
pd.date_range(‘起始日期’, ‘終止日期’)
pd.date_range(start=‘起始日期’, periods=10)
規則化時間戳
pd.date_range(start=‘起始日期’, periods=10, freq=‘選時間’)
星期
freq=‘W’
月
freq=‘M’
每個月最後一個工作日組成的索引
freq=‘BM’
小時
freq=‘4H’
時期及算術運算
pd.Period 表示時期,比如幾日,月或幾個月等。比如用來統計每個月的銷售額,就可以用時期作爲單位。
時期序列
直接用字符串
pd.period()
時期的頻率轉換
freq
- A-DEC: 以 12 月份作爲結束的年時期
- A-NOV: 以 11 月份作爲結束的年時期
- Q-DEC: 以 12 月份作爲結束的季度時期
以年爲週期,以一年中的 3 月份作爲年的結束(財年)
p.asfreq(‘A-MAR’)
季度時間頻率
Pandas 支持 12 種季度型頻率,從 Q-JAN 到 Q-DEC
Timestamp 和 Period 相互轉換
.to_period()
代碼
import pandas as pd
import numpy as np
from datetime import datetime
from datetime import timedelta
#時間日期
now = datetime.now()
print(now)
print(now.year, now.month, now.day)
### 時間差
print('時間差')
date1 = datetime(2016, 3, 20)
date2 = datetime(2016, 3, 16)
delta = date1 - date2
print(delta)
print(delta.days)
print(delta.total_seconds())
print(date2 + delta)
print(date2 + timedelta(4.5))
## 字符串和 datetime 轉換
#關於 datetime 格式定義,可以參閱 python 官方文檔
print('字符串和 datetime 轉換')
date = datetime(2016, 3, 20, 8, 30)
print(date)
print(str(date))
print(date.strftime('%Y-%m-%d %H:%M:%S'))
print(datetime.strptime('2016-03-20 09:30', '%Y-%m-%d %H:%M'))
## Pandas 裏的時間序列
#Pandas 裏使用 Timestamp 來表達時間
print('Pandas 裏的時間序列')
dates = [datetime(2016, 3, 1), datetime(2016, 3, 2), datetime(2016, 3, 3), datetime(2016, 3, 4)]
s = pd.Series(np.random.randn(4), index=dates)
print(s)
print(type(s.index))
print(type(s.index[0]))
## 日期範圍
### 生成日期範圍
print('日期範圍')
range1=pd.date_range('20160320', '20160331')
range2=pd.date_range(start='20160320', periods=10)
print(range1)
print(range2)
## 規則化時間戳
print('規則化時間戳')
timetime=pd.date_range(start='2016-03-20 16:23:32', periods=10, normalize=True)
print(timetime)
### 星期
timetime=pd.date_range(start='20160320', periods=10, freq='W')
print('星期{}'.format(timetime))
### 月
pd.date_range(start='20160320', periods=10, freq='M')
print('月{}'.format(timetime))
### 每個月最後一個工作日組成的索引
pd.date_range(start='20160320', periods=10, freq='BM')
print('最後工作日{}'.format(timetime))
### 小時
pd.date_range(start='20160320', periods=10, freq='4H')
print('小時{}'.format(timetime))
## 時期及算術運算
#pd.Period 表示時期,比如幾日,月或幾個月等。比如用來統計每個月的銷售額,就可以用時期作爲單位。
print('時期及算術運算')
p1 = pd.Period(2010)
print(p1)
p2 = p1 + 2
print(p2)
print(p2 - p1)
p1 = pd.Period(2016, freq='M')
print(p1)
print(p1 + 3)
## 時期序列
print('時期序列')
xulie=pd.period_range(start='2016-01', periods=12, freq='M')
print(xulie)
pd.period_range(start='2016-01', end='2016-10', freq='M')
print(xulie)
## 直接用字符串
print('直接用字符串')
index = pd.PeriodIndex(['2016Q1', '2016Q2', '2016Q3'], freq='Q-DEC')
print(index)
## 時期的頻率轉換
print('時期的頻率轉換')
p = pd.Period('2016', freq='A-DEC')
print(p)
print(p.asfreq('M', how='start'))
print(p.asfreq('M', how='end'))
p = pd.Period('2016-04', freq='M')
print(p)
print(p.asfreq('A-DEC'))
### 以年爲週期,以一年中的 3 月份作爲年的結束(財年)
print(p.asfreq('A-MAR'))
### 季度時間頻率
#Pandas 支持 12 種季度型頻率,從 Q-JAN 到 Q-DEC
p = pd.Period('2016Q4', 'Q-JAN')
print(p)
# 以 1 月份結束的財年中,2016Q4 的時期是指 2015-11-1 到 2016-1-31
year=p.asfreq('D', how='start'), p.asfreq('D', how='end')
print(year)
# 獲取該季度倒數第二個工作日下午4點的時間戳
p4pm = (p.asfreq('B', how='end') - 1).asfreq('T', 'start') + 16 * 60
print(p4pm)
# 轉換爲 timestamp
print(p4pm.to_timestamp())
### Timestamp 和 Period 相互轉換
print(' Timestamp 和 Period 相互轉換')
ts = pd.Series(np.random.randn(5), index = pd.date_range('2016-01-01', periods=5, freq='M'))
print(ts)
print(ts.to_period())
ts = pd.Series(np.random.randn(5), index = pd.date_range('2016-12-29', periods=5, freq='D'))
print(ts)
pts = ts.to_period(freq='M')
print(pts)
print(pts.groupby(level=0).sum())
# 轉換爲時間戳時,細部時間會丟失
print(pts.to_timestamp(how='end'))
重採樣 resample
- 高頻率 -> 低頻率 —— 降採樣:例:5 分鐘股票交易數據轉換爲日交易數據
- 低頻率 -> 高頻率 —— 升採樣
- 其他重採樣:每週三 (W-WED) 轉換爲每週五 (W-FRI)
重採樣方式
OHLC 重採樣
ts.resample(‘時間’).ohlc()
通過groupby重採樣
ts.index.to_period(‘M’)).sum()
升採樣
fill_method=‘ffill’ 向前插值
limit最多插三個
時期重採樣
‘A-DEC’:annual以年爲單位,DEC結尾是十二月
‘Q-DEC’:季度爲採樣
代碼
from datetime import datetime
from datetime import timedelta
import pandas as pd
import numpy as np
ts = pd.Series(np.random.randint(0, 50, 60), index=pd.date_range('2020-02-16 09:30', periods=60, freq='T'))
print(ts)
# 每五分鐘
# 0-4 分鐘爲第一組
print('每五分鐘')
sumsum=ts.resample('5min').sum()
print(sumsum)
# 0-4 分鐘爲第一組
sumsum=ts.resample('5min', label='right').sum()
print(sumsum)
### OHLC 重採樣
print('OHLC 重採樣')
ohlc=ts.resample('5min').ohlc()
print(ohlc)
### 通過 groupby 重採樣
print('通過 groupby 重採樣')
ts = pd.Series(np.random.randint(0, 50, 100), index=pd.date_range('2016-03-01', periods=100, freq='D'))
print(ts)
print(ts.groupby(lambda x: x.month).sum())
print(ts.groupby(ts.index.to_period('M')).sum())
### 升採樣和插值
print('升採樣和插值')
# 以周爲單位,每週五采樣
df = pd.DataFrame(np.random.randint(1, 50, 2), index=pd.date_range('2016-04-22', periods=2, freq='W-FRI'))
print(df)
sheng=df.resample('D')
print(sheng)
sheng=df.resample('D', fill_method='ffill', limit=3)
print(sheng)
# 以周爲單位,每週一採樣
print(df.resample('W-MON', fill_method='ffill'))
### 時期重採樣
df = pd.DataFrame(np.random.randint(2, 30, (24, 4)),
index=pd.period_range('2015-01', '2016-12', freq='M'),
columns=list('ABCD'))
print(df)
adf = df.resample('A-DEC').mean()
print(adf)
re=df.resample('A-MAY').mean()
print(re)
# 升採樣
sheng=adf.resample('Q-DEC')
print(sheng)
sheng=adf.resample('Q-DEC', fill_method='ffill')
print(sheng)
### 性能
n = 1000000
ts = pd.Series(np.random.randn(n),
index=pd.date_range('2000-01-01', periods=n, freq='10ms'))
print(len(ts))
print(ts.resample('10min').ohlc())
print(ts.resample('D').ohlc())
## 從文件中讀取日期序列
df = pd.read_csv('data/002001.csv', index_col='Date')
print(df)
print(df.index)
df = pd.read_csv('data/002001.csv', index_col='Date', parse_dates=True)
print(df.index)
wdf = df['Adj Close'].resample('W-FRI').ohlc()
print(wdf)
wdf['Volume'] = df['Volume'].resample('W-FRI').sum()
print(wdf)
### 自定義時間日期解析函數
def date_parser(s):
s = '2016/' + s
d = datetime.strptime(s, '%Y/%m/%d')
return d
df = pd.read_csv('data/custom_date.csv', parse_dates=True, index_col='Date', date_parser=date_parser)
print(df)
print(df.index)
每五分鐘採樣
重採樣方式
升採樣
時期重採樣
性能
讀取