中文

通过窗口函数释放时间序列数据的力量。本指南涵盖了数据分析的基本概念、实践案例和高级技巧。

时间序列分析:掌握窗口函数以获取数据洞见

时间序列数据,以其顺序性和时间依赖性为特征,在各行各业中无处不在。从追踪股票价格、监控网站流量,到分析传感器读数和预测销售趋势,从时间序列数据中提取有意义的洞见对于做出明智决策至关重要。窗口函数提供了一套强大而灵活的工具集,用于对与当前行相关的一组行进行计算,使其成为时间序列分析中不可或缺的工具。

理解时间序列数据

时间序列数据是按时间顺序索引的一系列数据点。这些数据点可以代表各种指标,例如:

分析时间序列数据涉及识别模式、趋势和季节性,这些可用于预测未来值、检测异常和优化业务流程。

窗口函数简介

窗口函数,也称为窗口聚合或分析函数,允许您对与当前行相关的一组行进行计算,而无需像传统的聚合函数(如 SUM, AVG, COUNT)那样将行分组为单个结果集。此功能对于时间序列分析特别有用,因为您经常需要计算移动平均、累积总和和其他基于时间的指标。

一个窗口函数通常由以下几个部分组成:

  1. 函数:要执行的计算(例如,AVG, SUM, RANK, LAG)。
  2. OVER 子句:定义用于计算的行窗口。
  3. PARTITION BY 子句(可选):将数据划分为分区,窗口函数独立应用于每个分区。
  4. ORDER BY 子句(可选):指定每个分区内行的顺序。
  5. ROWS/RANGE 子句(可选):定义窗口框架,即相对于当前行用于计算的一组行。

关键概念与语法

1. The OVER() Clause

OVER() 子句是窗口函数的核心。它定义了函数将要操作的行窗口。一个不带任何参数的简单 OVER() 子句会将整个结果集视为窗口。例如:

SQL 示例:

SELECT
  date,
  sales,
  AVG(sales) OVER()
FROM
  sales_data;

此查询计算了 sales_data 表中所有日期的平均销售额。

2. PARTITION BY

PARTITION BY 子句将数据划分为分区,窗口函数分别应用于每个分区。当您想为数据中的不同组计算指标时,这非常有用。

SQL 示例:

SELECT
  date,
  product_id,
  sales,
  AVG(sales) OVER (PARTITION BY product_id)
FROM
  sales_data;

此查询分别计算每个产品的平均销售额。

3. ORDER BY

ORDER BY 子句指定每个分区内行的顺序。这对于计算运行总计、移动平均和其他基于时间的指标至关重要。

SQL 示例:

SELECT
  date,
  sales,
  SUM(sales) OVER (ORDER BY date)
FROM
  sales_data;

此查询计算了随时间变化的销售额的累积总和。

4. ROWS/RANGE

ROWSRANGE 子句定义了窗口框架,即相对于当前行用于计算的一组行。ROWS 子句根据物理行号指定窗口框架,而 RANGE 子句则根据 ORDER BY 列的值指定窗口框架。

ROWS 示例:

SELECT
  date,
  sales,
  AVG(sales) OVER (ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
FROM
  sales_data;

此查询计算了过去3天(包括当天)的销售移动平均值。

RANGE 示例:

SELECT
  date,
  sales,
  AVG(sales) OVER (ORDER BY date RANGE BETWEEN INTERVAL '2' DAY PRECEDING AND CURRENT ROW)
FROM
  sales_data;

此查询计算了过去2天(包括当天)的销售移动平均值。请注意,`RANGE` 需要一个数值或日期/时间数据类型的排序列。

时间序列分析中常用的窗口函数

1. 滚动/移动平均

滚动平均,也称为移动平均,是一种广泛使用的技术,用于平滑时间序列数据中的短期波动并突显长期趋势。它通过对指定时间窗口内的值求平均来计算。

SQL 示例:

SELECT
  date,
  sales,
  AVG(sales) OVER (ORDER BY date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS moving_average_7_days
FROM
  sales_data;

此查询计算了7天销售移动平均值。

Python 示例 (使用 Pandas):

import pandas as pd

# Assuming you have a Pandas DataFrame called 'sales_df' with 'date' and 'sales' columns

sales_df['moving_average_7_days'] = sales_df['sales'].rolling(window=7).mean()

全球应用示例:一家跨国零售商可以使用30天移动平均来平滑每日销售波动,并识别不同地区的潜在销售趋势。

2. 累积求和

累积求和,也称为运行总计,计算截至当前行的值的总和。它对于跟踪随时间累积的总价值非常有用。

SQL 示例:

SELECT
  date,
  sales,
  SUM(sales) OVER (ORDER BY date) AS cumulative_sales
FROM
  sales_data;

此查询计算了随时间变化的销售额的累积总和。

Python 示例 (使用 Pandas):

import pandas as pd

# Assuming you have a Pandas DataFrame called 'sales_df' with 'date' and 'sales' columns

sales_df['cumulative_sales'] = sales_df['sales'].cumsum()

全球应用示例:一家国际电子商务公司可以使用累积销售额来跟踪新产品在不同市场发布后产生的总收入。

3. Lead 和 Lag

LEADLAG 函数允许您分别访问后续行或前序行的数据。它们对于计算周期性变化、识别趋势以及比较不同时间段的值非常有用。

SQL 示例:

SELECT
  date,
  sales,
  LAG(sales, 1, 0) OVER (ORDER BY date) AS previous_day_sales,
  sales - LAG(sales, 1, 0) OVER (ORDER BY date) AS sales_difference
FROM
  sales_data;

此查询计算了与前一天相比的销售差额。`LAG(sales, 1, 0)` 函数检索前一行的销售值(偏移量为1),如果没有前一行(例如第一行),则返回0(默认值)。

Python 示例 (使用 Pandas):

import pandas as pd

# Assuming you have a Pandas DataFrame called 'sales_df' with 'date' and 'sales' columns

sales_df['previous_day_sales'] = sales_df['sales'].shift(1)
sales_df['sales_difference'] = sales_df['sales'] - sales_df['previous_day_sales'].fillna(0)

全球应用示例:一家全球航空公司可以使用 lead 和 lag 函数来比较同一航线在不同周的机票销售情况,并识别潜在的需求波动。

4. Rank 和 Dense Rank

RANK()DENSE_RANK() 函数根据指定的排序为分区内的每一行分配一个排名。RANK() 分配的排名有间隙(例如,1, 2, 2, 4),而 DENSE_RANK() 分配的排名没有间隙(例如,1, 2, 2, 3)。

SQL 示例:

SELECT
  date,
  sales,
  RANK() OVER (ORDER BY sales DESC) AS sales_rank,
  DENSE_RANK() OVER (ORDER BY sales DESC) AS sales_dense_rank
FROM
  sales_data;

此查询按降序对销售值进行排名。

全球应用示例:一个全球在线市场可以使用排名函数来识别每个国家或地区的畅销产品。

高级技巧与应用

1. 组合窗口函数

可以组合窗口函数以执行更复杂的计算。例如,您可以计算累积总和的移动平均值。

SQL 示例:

SELECT
  date,
  sales,
  AVG(cumulative_sales) OVER (ORDER BY date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS moving_average_cumulative_sales
FROM
  (
    SELECT
      date,
      sales,
      SUM(sales) OVER (ORDER BY date) AS cumulative_sales
    FROM
      sales_data
  ) AS subquery;

2. 将窗口函数与条件聚合结合使用

您可以将窗口函数与条件聚合(例如,使用 CASE 语句)结合使用,以根据特定条件执行计算。

SQL 示例:

SELECT
  date,
  sales,
  AVG(CASE WHEN sales > 100 THEN sales ELSE NULL END) OVER (ORDER BY date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS moving_average_high_sales
FROM
  sales_data;

此查询仅计算销售额大于100的日子的销售移动平均值。

3. 时间序列分解

窗口函数可用于将时间序列分解为其趋势、季节性和残差部分。这涉及计算移动平均以估计趋势,识别季节性模式,然后减去趋势和季节性部分以获得残差。

4. 异常检测

窗口函数可通过计算移动平均和标准差来检测时间序列数据中的异常。落在某个范围之外的数据点(例如,与移动平均值相差+/- 3个标准差)可以被标记为异常。

跨行业实践案例

1. 金融

2. 零售

3. 制造业

4. 医疗保健

选择合适的工具

窗口函数可用于各种数据处理工具和编程语言,包括:

工具的选择取决于您的具体需求和技术专长。SQL 非常适合存储在关系数据库中的数据,而 Python 和 Spark 更灵活,适用于处理大型数据集和执行复杂分析。

最佳实践

结论

窗口函数是时间序列分析的强大工具,使您能够计算移动平均、累积总和、lead/lag 值以及其他基于时间的指标。通过掌握窗口函数,您可以从时间序列数据中解锁宝贵的洞见,并做出更明智的决策。无论您是在分析金融数据、销售数据、传感器数据还是网站流量数据,窗口函数都可以帮助您识别使用传统聚合技术难以检测的模式、趋势和异常。通过理解窗口函数的关键概念和语法并遵循最佳实践,您可以有效地利用它们来解决各个行业的各种实际问题。