7.4 时间序列的频率和重采样 (resample)


文档摘要

7.4 时间序列的频率和重采样 (resample) 7.4 时间序列的频率和重采样 (Resample) 时间序列数据通常以固定的频率记录,例如每天、每小时或每分钟。然而,在实际应用中,我们可能需要将时间序列数据转换为不同的频率,以便进行分析、建模或可视化。Pandas 提供了强大的 方法,用于改变时间序列的频率,这个过程被称为重采样。 7.4.1 重采样的概念 重采样是指将时间序列数据从一个频率转换为另一个频率。这可以分为两种类型: 升采样 (Upsampling): 将低频率数据转换为高频率数据。例如,将每日数据转换为每小时数据。升采样通常需要插值来填充新引入的时间点的值。 降采样 (Downsampling): 将高频率数据转换为低频率数据。例如,将每分钟数据转换为每日数据。

7.4 时间序列的频率和重采样 (resample)

7.4 时间序列的频率和重采样 (Resample)

时间序列数据通常以固定的频率记录,例如每天、每小时或每分钟。然而,在实际应用中,我们可能需要将时间序列数据转换为不同的频率,以便进行分析、建模或可视化。Pandas 提供了强大的 resample() 方法,用于改变时间序列的频率,这个过程被称为重采样。

7.4.1 重采样的概念

重采样是指将时间序列数据从一个频率转换为另一个频率。这可以分为两种类型:

  • 升采样 (Upsampling): 将低频率数据转换为高频率数据。例如,将每日数据转换为每小时数据。升采样通常需要插值来填充新引入的时间点的值。

  • 降采样 (Downsampling): 将高频率数据转换为低频率数据。例如,将每分钟数据转换为每日数据。降采样通常需要聚合操作,例如计算均值、总和或中位数。

7.4.2 resample() 方法

Pandas 的 resample() 方法是进行时间序列重采样的核心工具。它的基本语法如下:

DataFrame.resample(rule, axis=0, closed=None, label=None, convention='start', kind=None, loffset=None, base=0, on=None, level=None, origin='start_day')

其中,最重要的参数是 rule,它指定了新的频率。常用的频率字符串包括:

  • 'D': 每日

  • 'W': 每周

  • 'M': 每月

  • 'Q': 每季度

  • 'A': 每年

  • 'H': 每小时

  • 'T': 每分钟

  • 'S': 每秒

其他重要的参数包括:

  • closed: 指定在降采样中,哪个区间是闭合的。可以是 'right' (默认) 或 'left'

  • label: 指定在降采样中,使用哪个区间的标签。可以是 'right' (默认) 或 'left'

  • convention: 指定在升采样中,如何处理时间戳。可以是 'start' (默认) 或 'end'

  • kind: 指定是否将结果转换为时间戳索引或时间段索引。可以是 None (默认) 或 'period'

  • loffset: 调整输出时间标签。例如,'-1s' 将时间标签向前移动一秒。

  • origin: 用于生成新重采样索引的起始点。

7.4.3 降采样示例

import pandas as pd import numpy as np # 创建一个时间序列 dates = pd.date_range('2023-01-01', '2023-01-10', freq='H') ts = pd.Series(np.arange(len(dates)), index=dates) print("原始数据(每小时):\n", ts) # 降采样到每日,计算每日的均值 daily_mean = ts.resample('D').mean() print("\n降采样到每日(均值):\n", daily_mean) # 降采样到每日,计算每日的总和 daily_sum = ts.resample('D').sum() print("\n降采样到每日(总和):\n", daily_sum) # 降采样到每日,计算每日的最大值 daily_max = ts.resample('D').max() print("\n降采样到每日(最大值):\n", daily_max) # 使用 'left' 闭合区间和标签 daily_mean_left = ts.resample('D', closed='left', label='left').mean() print("\n降采样到每日(左闭合,左标签):\n", daily_mean_left)

代码解释:

  1. 首先,我们创建一个以小时为频率的时间序列。

  2. 然后,我们使用 resample('D').mean() 将其降采样到每日,并计算每日的均值。

  3. 类似地,我们计算每日的总和和最大值。

  4. 最后,我们展示了如何使用 closedlabel 参数来控制区间的闭合方式和标签。

mermaid图示:

7.4.4 升采样示例

import pandas as pd import numpy as np # 创建一个时间序列 dates = pd.date_range('2023-01-01', '2023-01-03', freq='D') ts = pd.Series(np.arange(len(dates)), index=dates) print("原始数据(每日):\n", ts) # 升采样到每小时,使用 ffill 填充缺失值 hourly_ffill = ts.resample('H').ffill() print("\n升采样到每小时(前向填充):\n", hourly_ffill) # 升采样到每小时,使用 bfill 填充缺失值 hourly_bfill = ts.resample('H').bfill() print("\n升采样到每小时(后向填充):\n", hourly_bfill) # 升采样到每小时,使用插值填充缺失值 hourly_interpolate = ts.resample('H').interpolate() print("\n升采样到每小时(插值):\n", hourly_interpolate)

代码解释:

  1. 首先,我们创建一个以天为频率的时间序列。

  2. 然后,我们使用 resample('H') 将其升采样到每小时。由于升采样会引入缺失值,我们需要使用 ffill() (前向填充)、bfill() (后向填充) 或 interpolate() (插值) 等方法来填充这些缺失值。

mermaid图示:

7.4.5 使用 origin 参数

origin 参数允许你指定重采样索引的起始点。这在某些情况下非常有用,例如,当你需要将数据与外部日历对齐时。

import pandas as pd import numpy as np # 创建一个时间序列 dates = pd.date_range('2023-01-05', '2023-01-10', freq='D') ts = pd.Series(np.arange(len(dates)), index=dates) print("原始数据:\n", ts) # 以 2023-01-01 为起始点进行重采样 daily_mean_origin = ts.resample('D', origin='2023-01-01').mean() print("\n重采样到每日(起始点为 2023-01-01):\n", daily_mean_origin)

代码解释:

在这个例子中,我们指定 origin='2023-01-01',这意味着重采样的索引将从 2023-01-01 开始,即使原始数据的起始日期是 2023-01-05。

7.4.6 使用 loffset 参数

loffset 参数允许你调整输出时间标签。这可以用于微调时间标签的位置,使其更符合你的需求。

import pandas as pd import numpy as np # 创建一个时间序列 dates = pd.date_range('2023-01-01', '2023-01-03', freq='H') ts = pd.Series(np.arange(len(dates)), index=dates) print("原始数据(每小时):\n", ts) # 降采样到每日,并向前移动时间标签 1 秒 daily_mean_loffset = ts.resample('D', loffset='-1s').mean() print("\n降采样到每日(时间标签向前移动 1 秒):\n", daily_mean_loffset)

代码解释:

在这个例子中,我们使用 loffset='-1s' 将时间标签向前移动了一秒。

7.4.7 重采样与分组 (groupby)

resample() 方法可以与 groupby() 方法结合使用,以进行更复杂的时间序列分析。例如,你可以按月对数据进行分组,然后计算每个月的平均值。

import pandas as pd import numpy as np # 创建一个包含多个类别的时间序列 dates = pd.date_range('2023-01-01', '2023-01-10', freq='D') df = pd.DataFrame({ 'value': np.random.randn(len(dates)), 'category': ['A', 'B'] * (len(dates) // 2) }, index=dates) print("原始数据:\n", df) # 按月分组,并计算每个类别的平均值 monthly_mean = df.groupby('category').resample('M')['value'].mean() print("\n按月分组的平均值:\n", monthly_mean)

代码解释:

在这个例子中,我们首先按 category 列对数据进行分组,然后使用 resample('M') 按月对每个类别的数据进行重采样,并计算每个月的平均值。

7.4.8 注意事项

  • 在进行重采样之前,请确保你的时间序列数据具有正确的时间戳索引。

  • 升采样通常需要插值或填充缺失值,选择合适的插值方法取决于数据的性质。

  • 降采样通常需要聚合操作,选择合适的聚合函数取决于你的分析目标。

  • resample() 方法返回一个 Resampler 对象,你需要调用聚合函数(例如 mean(), sum(), max())来获得最终结果。

  • 理解 closedlabel 参数对于正确处理降采样非常重要。

7.4.9 总结

Pandas 的 resample() 方法是处理时间序列数据的强大工具。通过掌握 resample() 方法的各种参数和用法,你可以轻松地改变时间序列的频率,并进行各种时间序列分析。 理解升采样和降采样的区别,以及如何处理引入的缺失值,是有效使用 resample() 的关键。 结合 groupby() 方法可以进行更高级的分析。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U