欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python 时间序列

程序员文章站 2022-05-02 19:02:24
...


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)

python 时间序列
我们用 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)

python 时间序列