Python Pandas – 将 DateTimeIndex 的时间戳对齐到最近的频率
在 Pandas 中,我们可以使用 DateTimeIndex 来表示时间序列数据。DateTimeIndex 具有一些有用的方法和属性,我们可以使用它们来操作时间序列数据。在这篇文章中,我们将学习如何将 DateTimeIndex 的时间戳对齐到最近的频率。
pandas.date_range() 函数
在讲解将时间戳对齐到最近的频率之前,我们先介绍一下 pandas.date_range() 函数。pandas.date_range(start, end, periods, freq, tz, normalize, name) 函数用于创建一个 DatetimeIndex,它可以生成一系列连续的时间戳。下面是这个函数的参数说明:
- start:开始时间,格式为 datetime、Timestamp 或字符串,如果没有指定,就使用当前日期时间。
- end:结束时间,格式为 datetime、Timestamp 或字符串,如果没有指定,就使用当前日期时间。
- periods:时间序列的长度,要么指定 periods,要么指定 end、freq(频率)中的一个。
- freq:频率,例如 ‘D’(每天)、‘H’(每小时)、‘T’(每分钟)、‘S’(每秒)等。
- tz:时区,例如 ‘Asia/Shanghai’。
- normalize:是否将时间设置为午夜,默认为 False。
- name:DatetimeIndex 对象的名称。
我们可以通过下面的代码来创建一个包含 5 个日期的 DatetimeIndex 对象:
import pandas as pd
dates = pd.date_range('20200101', periods=5)
print(dates)
输出:
DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04',
'2020-01-05'],
dtype='datetime64[ns]', freq='D')
我们可以看到,这里的 freq 参数的默认值是 ‘D’,即每天。如果我们想要每小时的时间序列,可以将 freq 设置为 ‘H’:
import pandas as pd
dates = pd.date_range('20200101', periods=5, freq='H')
print(dates)
输出:
DatetimeIndex(['2020-01-01 00:00:00', '2020-01-01 01:00:00',
'2020-01-01 02:00:00', '2020-01-01 03:00:00',
'2020-01-01 04:00:00'],
dtype='datetime64[ns]', freq='H')
resample() 方法
pandas 也提供了一个 resample() 方法,它可以将时间序列数据转换为另一种频率。resample() 方法的语法如下:
dataframe.resample(rule, how=None, axis=0, fill_method=None, closed=None, label=None)
这里的 dataframe 是一个 DataFrame 对象,rule 是一个字符串,表示新的频率。resample() 方法会根据规则重新采样数据,并返回一个新的 DataFrame。
例如,如果我们有一个包含每小时某个行为的数据集,我们想要将其转换为每天的数据集。
import pandas as pd
import numpy as np
# 创建一个包含随机数据的 DataFrame
rng = pd.date_range(start='2019/01/01', end='2019/12/31', freq='H')
df = pd.DataFrame({'date': rng, 'value': np.random.randint(1, 24, len(rng))})
# 将逐小时的数据转换为逐日的数据
df = df.set_index('date').resample('D').sum().reset_index()
print(df.head())
输出:
date value
0 2019-01-01 437
1 2019-01-02 492
2 2019-01-03 475
3 2019-01-04 385
4 2019-01-05 420
我们可以看到,原来每小时的数据被合并成了每天的数据。
asfreq() 方法接下来,我们介绍 DateTimeIndex 对象的 asfreq() 方法。asfreq() 方法可用于将时间戳向前或向后填充到最近的频率。asfreq() 方法的语法如下:
dataframe.asfreq(freq, method=None, how=None, fill_value=None)
这里的 dataframe 是一个 DataFrame 对象,freq 是一个字符串,表示新的频率。asfreq() 方法会根据规则重新采样数据,并返回一个新的 DataFrame。method 参数用于确定如何填充数据,how 参数用于确定填充数据的方式,fill_value 参数用于指定填充值。
例如,我们有一个包含每小时气温的数据集,我们想要将其转换为每天的数据集,并向前填充数据。
import pandas as pd
import numpy as np
# 创建一个包含随机数据的 DataFrame
rng = pd.date_range(start='2019/01/01', end='2019/12/31', freq='H')
df = pd.DataFrame({'date': rng, 'temperature': np.random.randint(-10, 40, len(rng))})
# 将逐小时的数据转换为逐日的数据,并向前填充数据
df = df.set_index('date').asfreq('D', method='ffill').reset_index()
print(df.head())
输出:
date temperature
0 2019-01-01 -10.0
1 2019-01-02 2.0
2 2019-01-03 16.0
3 2019-01-04 -3.0
4 2019-01-05 -4.0
我们可以看到,原来每小时的数据被合并成了每天的数据,并使用向前填充的方式填充缺失值。
bdate_range() 函数
除了 date_range() 函数,pandas 还提供了 bdate_range() 函数。bdate_range() 会生成一系列日期,排除周末和其他非工作日。bdate_range() 函数的语法如下:
pandas.bdate_range(start=None, end=None, periods=None, freq='B', **kwargs)
这里的 start、end、periods 和 freq 参数跟 date_range() 函数一样。下面是一个示例代码:
import pandas as pd
dates = pd.bdate_range(start='20210101', end='20210110')
print(dates)
输出:
DatetimeIndex(['2021-01-01', '2021-01-04', '2021-01-05', '2021-01-06',
'2021-01-07', '2021-01-08'],
dtype='datetime64[ns]', freq='B')
我们可以看到,2021 年 1 月 2 日和 2021 年 1 月 3 日被排除了。
代码示例
接下来,我们演示一下如何将 DateTimeIndex 的时间戳对齐到最近的频率。
import pandas as pd
# 创建一个包含随机数据的 DataFrame
rng = pd.date_range(start='20210101', end='20210110', freq='H')
df = pd.DataFrame({'date': rng, 'value': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]})
# 将 2021 年 1 月 1 日、2 日排除
business_dates = pd.bdate_range(start='20210101', end='20210110')
# 将时间戳对齐到最近的工作日
df = df.set_index('date').asfreq('B', method='ffill').reset_index()
# 筛选出工作日
df = df[df['date'].isin(business_dates)]
# 输出结果
print(df)
输出:
date value
0 2021-01-01 00:00:00 0
2 2021-01-04 00:00:00 2
2 2021-01-05 00:00:00 2
2 2021-01-06
输出:
date value
0 2021-01-01 00:00:00 0
2 2021-01-04 00:00:00 2
3 2021-01-05 00:00:00 3
4 2021-01-06 00:00:00 4
5 2021-01-07 00:00:00 5
6 2021-01-08 00:00:00 6
我们可以看到,原来包含周末的时间序列被转换成了只包含工作日的时间序列。
结论
在本文中,我们学习了如何使用 pandas 提供的一些方法和函数来处理 DateTimeIndex 的时间戳,并将其对齐到最近的频率。我们介绍了 pandas.date_range() 函数、resample() 方法、asfreq() 方法和 bdate_range() 函数。在实际工作中,我们可以根据需求灵活运用这些方法来处理时间序列数据。
极客笔记