python 時間序列

zhuo木鳥發表於2020-12-04


python 有一個標準庫 datetime,可以用來表示時間、日期等。也可以實現字串和日期、時間變數的相互轉換。

型別使用說明
date日期(月、日、年)
time時間(時、分、秒)
datetime日期和時間
timedelta兩個 datetime 型別的差,可以用來進行日期的加減運算

基礎

生成日期

日期可以用 date 生成,用法是datetime.date(年,月,日) 。並可以用 xx.year、xx.month、xx.day 來顯示 xx 變數的年份、月份和日子。

import datetime
date = datetime.date(2019,6,1)
print(data)
print(data.year,data.month,data.day)

2019-06-01
2019 6 1

生成時間·

可以用 time 類來實現,基本用法是 datetime.time(時,分,秒)

time = datetime.time(10,20,25)
print(time)
print(time.hour,time.minute,time.second)

10:20:25
10 20 25

日期加減

now = datetime.datetime.now()
print(now)
now = datetime.datetime(2020,12,4)
birth = datetime.datetime(1999,9,13)
delta = now - birth
print(delta)
type(delta)
date = birth + datetime.timedelta(9999)    # 9999 是 day 為單位
print(date)

2020-12-04 10:09:52.867681
7753 days, 0:00:00
2027-01-28 00:00:00

日期型別的轉換

字串和 datetime 型別可以用 strftime 和 strptime 函式相互轉換。

from datetime import datetime
stamp = datetime(2020,12,5)
print(stamp.strftime('%Y/%m/%d'))

2020/12/05

字串格式表示如下:

型別描述
%Y四位數的年份
%y兩位數的年份
%m兩位的年份
%d兩位的日期
%H小時
%M分鐘
%S

用 datetime 類的 strptime 方法可以將字串轉換成 datetime 型別的資料:

str1 = '2020-12-12'
date = datetime.strptime(str1,'%Y-%m-%d')
print(date)
strlist= ['2020-12-1','2020-12-2','2020-12-3','2020-12-4']    # 字串列表
print([datetime.strptime(str1,'%Y-%m-%d') for str1 in strlist])  # 列表轉 datetime 類別的列表

2020-12-12 00:00:00
[datetime.datetime(2020, 12, 1, 0, 0), datetime.datetime(2020, 12, 2, 0, 0), datetime.datetime(2020, 12, 3, 0, 0), datetime.datetime(2020, 12, 4, 0, 0)]

日期序列

日期序列一般是用 DataFrame 或 Series 類別轉換而來,並且用其表示

用 pd 生成日期序列

可以直接使用 pd.date_range(start = ‘xxxx-xx-xx’ [,end = ‘xxxx-xx-xx’, periods = x, freq = ‘D’]) 來生成日期序列

datelist = pd.date_range(start='2020-12-4',end='2020-12-12')    #這裡 start 和 end 都有包括進去
print(datelist)
df['日期1'] = datelist
display(df)
stamp = df['日期1'][0]
print(type(stamp))

DatetimeIndex([‘2020-12-04’, ‘2020-12-05’, ‘2020-12-06’, ‘2020-12-07’,
‘2020-12-08’, ‘2020-12-09’, ‘2020-12-10’, ‘2020-12-11’,
‘2020-12-12’, ‘2020-12-13’],
dtype=‘datetime64[ns]’, freq=‘D’)

注意,這裡生成的資料型別是 DatetimeIndex 物件,而不是 list 。不過,也可以將其作為資料,新增到 dataframe 中。

periods 引數接受整數變數,若用到 periods 引數,則 start 和 end 引數使用其一。例如使用 start 引數,則生成的 datetime 序列會 以 start 為起點,順序生成 periods 個 datetime 變數。用 end ,則會向前生成:

datelist = pd.date_range(end='2020-12-13',periods=6) 
print(datelist)

DatetimeIndex([‘2020-12-08’, ‘2020-12-09’, ‘2020-12-10’, ‘2020-12-11’,
‘2020-12-12’, ‘2020-12-13’],
dtype=‘datetime64[ns]’, freq=‘D’)

freq 引數接受字串,配合其他引數,決定生成的 datetime 變數間隔。其取值為

取值說明
D以日期為間隔
B以工作日為間隔
H以小時為間隔
T以分鐘為間隔
S以秒為間隔
M以每月的最後一個工作日為間隔
BM工作日月底日期
MS工作日月初日期
A-JAN指定月份的工作日月底日期
datelist = pd.date_range(start='2020-12-13',end='2022-12-13',freq='M') 
print(datelist)
datelist = pd.date_range(start='2020-12-13',end='2022-12-13',freq='A-JAN') 
print(datelist)
datelist = pd.date_range(start='2020-12-13',end='2022-12-13',freq='MS') 
print(datelist)
datelist = pd.date_range(start='2020-12-13',end='2021-12-14',freq='5H11T5S') 
print(datelist)

DatetimeIndex([‘2020-12-31’, ‘2021-01-31’, ‘2021-02-28’, ‘2021-03-31’,
‘2021-04-30’, ‘2021-05-31’, ‘2021-06-30’, ‘2021-07-31’,
‘2021-08-31’, ‘2021-09-30’, ‘2021-10-31’, ‘2021-11-30’,
‘2021-12-31’, ‘2022-01-31’, ‘2022-02-28’, ‘2022-03-31’,
‘2022-04-30’, ‘2022-05-31’, ‘2022-06-30’, ‘2022-07-31’,
‘2022-08-31’, ‘2022-09-30’, ‘2022-10-31’, ‘2022-11-30’],
dtype=‘datetime64[ns]’, freq=‘M’)

DatetimeIndex([‘2021-01-31’, ‘2022-01-31’], dtype=‘datetime64[ns]’, freq=‘A-JAN’)

DatetimeIndex([‘2021-01-01’, ‘2021-02-01’, ‘2021-03-01’, ‘2021-04-01’,
‘2021-05-01’, ‘2021-06-01’, ‘2021-07-01’, ‘2021-08-01’,
‘2021-09-01’, ‘2021-10-01’, ‘2021-11-01’, ‘2021-12-01’,
‘2022-01-01’, ‘2022-02-01’, ‘2022-03-01’, ‘2022-04-01’,
‘2022-05-01’, ‘2022-06-01’, ‘2022-07-01’, ‘2022-08-01’,
‘2022-09-01’, ‘2022-10-01’, ‘2022-11-01’, ‘2022-12-01’],
dtype=‘datetime64[ns]’, freq=‘MS’)

DatetimeIndex([‘2020-12-13 00:00:00’, ‘2020-12-13 05:11:05’,
‘2020-12-13 10:22:10’, ‘2020-12-13 15:33:15’,
‘2020-12-13 20:44:20’, ‘2020-12-14 01:55:25’,
‘2020-12-14 07:06:30’, ‘2020-12-14 12:17:35’,
‘2020-12-14 17:28:40’, ‘2020-12-14 22:39:45’,

‘2021-12-12 00:15:25’, ‘2021-12-12 05:26:30’,
‘2021-12-12 10:37:35’, ‘2021-12-12 15:48:40’,
‘2021-12-12 20:59:45’, ‘2021-12-13 02:10:50’,
‘2021-12-13 07:21:55’, ‘2021-12-13 12:33:00’,
‘2021-12-13 17:44:05’, ‘2021-12-13 22:55:10’],
dtype=‘datetime64[ns]’, length=1695, freq=‘18665S’)

從字串序列生成日期序列

首先我們生成示例資料,其中 時間 列是一個字串序列,我們考慮將其轉成 datetime 型別的序列:

import pandas as pd
import numpy as np
datestr = ['2020-12-%s'%str(i+1) for i in range(10)]
print(datestr,len(datestr))
data = np.random.randn(10,3)
df = pd.DataFrame(data,columns=['列1','列2','列3'])
df['日期'] = datestr
display(df)

在這裡插入圖片描述
我們用 pd.to_datetime() 來實現字串序列和日期序列的轉換

df['日期'] = pd.to_datetime(df['日期'])
stamp = df['日期'][0]
print(type(stamp))
print(stamp.strftime('%F'))
print(stamp.year,stamp.month,stamp.day)

日期字串要求使用的格式為 %Y-%m-%d,若是其他的,會報錯。因此可以用 strptime 的方法實現:

df['日期'] = [datetime.strptime(i,'%Y-%m-%d') for i in df['日期']]
stamp = df['日期'][0]
print(type(stamp))
print(stamp.strftime('%F'))
print(stamp.year,stamp.month,stamp.day)

無論是那種日期字串格式,在變成 datetime 型別時,都是用 年-月-日 表示。

將日期序列設定成 index

df = df.set_index('日期')

以日期序列為索引的 df 的妙用

display(df)
df['2020-12-01':'2020-12-05']   # 此時也包含 2020-12-05,這與切片不同

在以日期序列作為索引後,仍舊可以使用 DataFrame 的切片

df[0:5] #切片不包括5

有了日期序列作為索引,可以用年份、月份來搜尋資料,如:

df['2020']
df['2020-1':'2020-3']   

日期序列的移動

日期序列的移動可以用 .shift 方法實現,具體用法如下:

df['日期1'].shift(2,freq='D')

日期
2020-12-03 2020-12-04
2020-12-04 2020-12-05
2020-12-05 2020-12-06
2020-12-06 2020-12-07
2020-12-07 2020-12-08
2020-12-08 2020-12-09
2020-12-09 2020-12-10
2020-12-10 2020-12-11
2020-12-11 2020-12-12
2020-12-12 2020-12-13
Name: 日期1, dtype: datetime64[ns]

若日期序列以便成 index,則不能修改

取樣

取樣是將連續的幾組資料取出來,並使用聚合函式進行計算,可以實現資料透視的目的。

w = pd.date_range(start='2020/6/1',end='2020/12/4',freq='D')
df = pd.DataFrame(index=w,data=np.arange(len(w)),columns=['列'])
df.head()
display(df['列'].resample('M').mean()

2020-06-30 14.5
2020-07-31 45.0
2020-08-31 76.0
2020-09-30 106.5
2020-10-31 137.0
2020-11-30 167.5
2020-12-31 184.5
Freq: M, Name: 列, dtype: float64

也可以用連續 3 天來進行分組:

display(df['列'].resample('3D').mean()

2020-06-01 1
2020-06-04 4
2020-06-07 7
2020-06-10 10
2020-06-13 13

2020-11-22 175
2020-11-25 178
2020-11-28 181
2020-12-01 184
2020-12-04 186
Freq: 3D, Name: 列, Length: 63, dtype: int32

在討論 dataframe 的時候,我們討論了 groupby 方法。使用 groupby 的方法,我們可以用類別變數,來實現資料透視。但是,如果有了時間序列,也可以使用 groupby 方法進行資料透視,此時可以用時間序列的 月 來進行分組,也可以做到類似“類別變數”的作用:

grouped = df.groupby(df.index.month).mean()
display(grouped)

在這裡插入圖片描述

相關文章