时序数据
import numpy as np
import pandas as pd
一、时序中的基本对象
(1) 时间戳 (Date times): pandas 中称为 Timestamp,一系列的时间戳可以组成 DatetimeIndex ,将它放到 Series 中后, Series 的类型就变为了 datetime64[ns] ,如果有涉及时区则为 datetime64[ns, tz] ,其中tz是timezone的简写
(2) 时间差(Time deltas): pandas中利用 Timedelta 来表示,一系列的时间差就组成了 TimedeltaIndex , 而将它放到 Series 中后, Series 的类型就变为了 timedelta64[ns]
(3) 时间段(Time spans): 在 pandas 利用 Period 来表示,一系列的时间段就组成了 PeriodIndex , 而将它放到 Series 中后, Series 的类型就变为了 Period
(4) 日期偏置(Date offsets): pandas中利用DateOffset
二、时间戳
1. Timestamp的构造与属性
(1) pd.Timestamp
ts = pd.Timestamp('2020/1/1')
ts
Timestamp('2020-01-01 00:00:00')
ts = pd.Timestamp('2020-1-1 08:10:30')
ts
Timestamp('2020-01-01 08:10:30')
(2) year, month, day, hour, min, second 可以获取具体的数值
在 pandas 中,时间戳的最小精度为纳秒 ns
ts.year
2020
(3) pd.Timestamp.max 和 pd.Timestamp.min获取时间戳表示的范围
pd.Timestamp.max
Timestamp('2262-04-11 23:47:16.854775807')
pd.Timestamp.min
Timestamp('1677-09-21 00:12:43.145225')
pd.Timestamp.max.year - pd.Timestamp.min.year
585
2. Datetime序列的生成
(1) to_datetime把一列时间戳格式的对象转换成为 datetime64[ns] 类型的时间序列
pd.to_datetime(['2020-1-1', '2020-1-3', '2020-1-6'])
DatetimeIndex(['2020-01-01', '2020-01-03', '2020-01-06'], dtype='datetime64[ns]', freq=None)
df = pd.read_csv('data/learn_pandas.csv')
s = pd.to_datetime(df.Test_Date)
s.head()
0 2019-10-05
1 2019-09-04
2 2019-09-12
3 2020-01-03
4 2019-11-06
Name: Test_Date, dtype: datetime64[ns]
时间戳的格式不满足转换时,可以强制使用 format 进行匹配
temp = pd.to_datetime(['2020\\1\\1','2020\\1\\3'],format='%Y\\%m\\%d')
temp
DatetimeIndex(['2020-01-01', '2020-01-03'], dtype='datetime64[ns]', freq=None)
上面由于传入的是列表,而非 pandas 内部的 Series ,因此返回的是 DatetimeIndex ,如果想要转为 datetime64[ns] 的序列,需要显式用 Series 转化
pd.Series(temp).head()
0 2020-01-01
1 2020-01-03
dtype: datetime64[ns]
表的多列时间属性拼接转为时间序列的 to_datetime 操作
此时的列名必须和以下给定的时间关键词列名一致,也就是year, month, day, hour, min, second
df_date_cols = pd.DataFrame({
'year': [2020, 2020],'month': [1, 1],
'day': [1, 2], 'hour': [10, 20],
'minute': [30, 50],'second': [20, 40]})
pd.to_datetime(df_date_cols)
0 2020-01-01 10:30:20
1 2020-01-02 20:50:40
dtype: datetime64[ns]
(2) date_range 是一种生成连续间隔时间的一种方法
参数:开始或结束日期如果作为端点则它会被包含
start: 开始时间
end: 结束时间
freq: 时间间隔
periods: 时间戳个数
pd.date_range('2020-1-1','2020-1-21', freq='10D') # 包含
DatetimeIndex(['2020-01-01', '2020-01-11', '2020-01-21'], dtype='datetime64[ns]', freq='10D')
pd.date_range('2020-1-1','2020-2-28', freq='10D')
DatetimeIndex(['2020-01-01', '2020-01-11', '2020-01-21', '2020-01-31',
'2020-02-10', '2020-02-20'],
dtype='datetime64[ns]', freq='10D')
pd.date_range('2020-1-1','2020-2-28', periods=6) # 由于结束日期无法取到,freq不为10天
DatetimeIndex(['2020-01-01 00:00:00', '2020-01-12 14:24:00',
'2020-01-24 04:48:00', '2020-02-04 19:12:00',
'2020-02-16 09:36:00', '2020-02-28 00:00:00'],
dtype='datetime64[ns]', freq=None)
3. 练一练
Timestamp 上定义了一个 value 属性,其返回的整数值代表了从1970年1月1日零点到给定时间戳相差的纳秒数,请利用这个属性构造一个随机生成给定日期区间内日期序列的函数。
**思路:**首先测试一下value的使用,得到的是一个值,使用pd.to_date可以将其转换为日期,我们只需要将日期区间的value值取出,然后使用random.sample生成随机序列,再转换为日期,即可得到我们想要的结果
import random
ts = pd.Timestamp('2020/1/1')
pd.to_datetime(ts.value)
Timestamp('2020-01-04 07:08:36')
pd.to_datetime(1578121716000000000)
Timestamp('2020-01-04 07:08:36')
解答
def dt_random(date_start,date_end,n):
start = date_start.value
end = date_end.value
s = pd.Series(random.sample(range(int(start/1000000000),int(end/1000000000)),n))*1000000000
#我们只需要到秒的数据,所以需要将数值转换一下
return pd.to_datetime(s.tolist())
dt_random(pd.to_datetime('2020-1-1'),pd.to_datetime('2020-1-21'),4)
DatetimeIndex(['2020-01-03 13:41:52', '2020-01-04 23:21:12',
'2020-01-11 10:30:12', '2020-01-06 10:45:15'],
dtype='datetime64[ns]', freq=None)
(3) asfreq:改变序列采样频率的方法
根据给定的 freq 对序列进行类似于 reindex 的操作
s = pd.Series(np.random.rand(5),index=pd.to_datetime(['2020-1-%d'%i for i in range(1,10,