Pandas时间序列数据处理
1.好用的Python库
2.Pandas历史
3.时序数据处理
本文部分内容来源为:joyful-pandas
3.1 时序中的基本对象
3.2 python中的datetime模块
3.3. 时间戳(Date times)的构造与属性
3.4. 时间差(Timedelta)的构造与属性
概念 | 单元素类型 | 数组类型 | pandas数据类型 |
Date times | Timestamp |
DatetimeIndex |
datetime64[ns] |
Time deltas | Timedelta |
TimedeltaIndex |
timedelta64[ns] |
Time spans | Period |
PeriodIndex |
period[freq] |
Date offsets | DateOffset |
None |
None |
1.Timedelta生成
1.通过pd.Timedelta来构造
时间差可以理解为两个时间戳的差,这里也可以通过pd.Timedelta来构造:
通过Timestamp构建时间差Timedelta
import numpy as np import pandas as pd pd.Timestamp('20220102 08:00:00')-pd.Timestamp('20220101 07:35:00')
输出为:
Timedelta('1 days 00:25:00')
通过Timedelta生成
pd.Timedelta(days=1, minutes=25) # 需要注意加s # pd.Timedelta('1 days 25 minutes') # 字符串生成 同上一样
输出:
Timedelta('1 days 00:25:00')
2 to_timedelta生成
to_timedelta生成-精确到 20.5us
精确到 20.5us pd.to_timedelta('20.5us')
输出为:
Timedelta('0 days 00:00:00.000020500')
to_timedelta生成-构建一个Timedelta序列
pd.to_timedelta(['2 days 04:06:10.00006', '15.5us', 'nan'])
输出为:
TimedeltaIndex(['2 days 04:06:10.000060', '0 days 00:00:00.000015500', NaT], dtype='timedelta64[ns]', freq=None)
to_timedelta生成-指定单位
pd.to_timedelta(np.arange(6), unit='d')
输出为:
TimedeltaIndex(['0 days', '1 days', '2 days', '3 days', '4 days', '5 days'], dtype='timedelta64[ns]', freq=No
3. timedelta_range生成
与date_range一样,时间差序列也可以用timedelta_range来生成,它们两者具有一致的参数:
import numpy as np import pandas as pd pd.timedelta_range(start='2 day', periods=5, freq='6H', closed='right')
输出为:
TimedeltaIndex(['2 days 06:00:00', '2 days 12:00:00', '2 days 18:00:00','3 days 00:00:00'], dtype='timedelta64[ns]', freq='6H')
4. dt对象
对于Timedelta序列,同样也定义了dt对象,上面主要定义了的属性包括days, seconds, mircroseconds, nanoseconds,它们分别返回了对应的时间差特征。
2. Timedelta的运算
时间差支持的常用运算有三类:与标量的乘法运算、与时间戳的加减法运算、与时间差的加减法与除法运算:
# 初始化Timedelta td1 = pd.Timedelta(days=1) # Timedelta('1 days 00:00:00') td2 = pd.Timedelta(days=3) # Timedelta('3 days 00:00:00') # 与标量的计算 td1 * 2 # Timedelta('2 days 00:00:00') # 与时间差的计算 td2 - td1 # Timedelta('2 days 00:00:00') # 与时间戳的计算 ts = pd.Timestamp('20200101') td1 = pd.Timedelta(days=1) # Timedelta('1 days 00:00:00') ts + td1 # Timestamp('2020-01-02 00:00:00')
时间差序列计算:
# 定义时间差 td1 = pd.timedelta_range(start='1 days', periods=5) td1 """ # TimedeltaIndex(['1 days', '2 days', '3 days', '4 days', '5 days'], dtype='timedelta64[ns]', freq='D') """ td2 = pd.timedelta_range(start='12 hours', freq='2H', periods=5) td2 """ TimedeltaIndex(['0 days 12:00:00', '0 days 14:00:00', '0 days 16:00:00', '0 days 18:00:00', '0 days 20:00:00'], dtype='timedelta64[ns]', freq='2H') """ ts = pd.date_range('20200101', '20200105') ts """ DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04', '2020-01-05'],
时间差序列与标量计算:
td1 * 5 # TimedeltaIndex(['5 days', '10 days', '15 days', '20 days', '25 days'], dtype='timedelta64[ns]', freq='5D')
输出为:
TimedeltaIndex(['5 days', '10 days', '15 days', '20 days', '25 days'], dtype='timedelta64[ns]', freq='5D')
时间差序列与series计算
td1 * pd.Series(list(range(5))) # 逐个相乘
输出为:
0 0 days 1 2 days 2 6 days 3 12 days 4 20 days dtype: timedelta64[ns]
时间差序列直接计算
td1 - td2
输出为:
TimedeltaIndex(['0 days 12:00:00', '1 days 10:00:00', '2 days 08:00:00', '3 days 06:00:00', '4 days 04:00:00'], dtype='timedelta64[ns]', freq=None)
时间差序列与时间戳计算:
td1 + pd.Timestamp('20200101')
输出为:
DatetimeIndex(['2020-01-02', '2020-01-03', '2020-01-04', '2020-01-05', '2020-01-06'], dtype='datetime64[ns]', freq='D')
3.5 时间段Time spans的构造与属性:Period
概念 | 单元素类型 | 数组类型 | pandas数据类型 |
Date times | Timestamp |
DatetimeIndex |
datetime64[ns] |
Time deltas | Timedelta |
TimedeltaIndex |
timedelta64[ns] |
Time spans | Period |
PeriodIndex |
period[freq] |
Date offsets | DateOffset |
None |
None |
1. 通过Period生成
# 生成一个以2022-01开始,月为频率的时间构造器 # pd.Period()参数:一个时间戳 + freq 参数 → freq 用于指明该 period 的长度,时间戳则说明该 period 在时间轴上的位置 period_d = pd.Period('2022', freq = 'M') print(period_d, type(period_d)) # 通过加减整数,将周期整体移动 # 这里是按照 月、年 移动 print('period_d + 1的结果为:',period_d + 1) print('period_d - 2的结果为:',period_d - 2) print(pd.Period('2022', freq = 'A-DEC') - 1)
输出为:
2022-01 <class 'pandas._libs.tslibs.period.Period'> period_d + 1的结果为: 2022-02 period_d - 2的结果为: 2021-11 2021
2. 通过period_range方法生成
# pd.period_range()创建时期范围 prng = pd.period_range('1/1/2021', '1/1/2022', freq='M') print(prng,type(prng)) print(prng[0],type(prng[0])) # 数据格式为PeriodIndex,单个数值为Period
输出为:
PeriodIndex(['2021-01', '2021-02', '2021-03', '2021-04', '2021-05', '2021-06', '2021-07', '2021-08', '2021-09', '2021-10', '2021-11', '2021-12', '2022-01'], dtype='period[M]', freq='M') <class 'pandas.core.indexes.period.PeriodIndex'> 2021-01 <class 'pandas._libs.tslibs.period.Period'>
构建series,指定索引为PeriodIndex
ts = pd.Series(np.arange(len(prng)), index = prng) print(ts,type(ts)) print(ts.index) # 时间序列
输出为:
2021-01 0 2021-02 1 2021-03 2 2021-04 3 2021-05 4 2021-06 5 2021-07 6 2021-08 7 2021-09 8 2021-10 9 2021-11 10 2021-12 11 2022-01 12 Freq: M, dtype: int32 <class 'pandas.core.series.Series'> PeriodIndex(['2021-01', '2021-02', '2021-03', '2021-04', '2021-05', '2021-06', '2021-07', '2021-08', '2021-09', '2021-10', '2021-11', '2021-12', '2022-01'], dtype='period[M]', freq='M')
3. asfreq:频率转换
# asfreq:频率转换 # Period('2020', freq = 'A-DEC')可以看成多个时间期的时间段中的游标 # Timestamp表示一个时间戳,是一个时间截面;Period是一个时期,是一个时间段!!但两者作为index时区别不大 p = pd.Period('2020','A-DEC') print("p--->",p) print("p--->",p.asfreq('M', how = 'start')) # 也可写 how = 's' print("p--->",p.asfreq('D', how = 'end')) # 也可写 how = 'e' # 通过.asfreq(freq, method=None, how=None)方法转换成别的频率 print('*'*10) prng = pd.period_range('2020','2021',freq = 'M') ts1 = pd.Series(np.random.rand(len(prng)), index = prng) ts2 = pd.Series(np.random.rand(len(prng)), index = prng.asfreq('D', how = 'start')) print(ts1.head(),len(ts1)) print(ts2.head(),len(ts2)) # asfreq也可以转换TIMESeries的index
输出为:
p---> 2020 p---> 2020-01 p---> 2020-12-31 ********** 2020-01 0.602249 2020-02 0.470631 2020-03 0.515769 2020-04 0.221421 2020-05 0.959175 Freq: M, dtype: float64 13 2020-01-01 0.115775 2020-02-01 0.309005 2020-03-01 0.738583 2020-04-01 0.785310 2020-05-01 0.574895 Freq: D, dtype: float64 13