python 时间序列
文章目录
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)