NumPy 中文教程

第一部分:基础认知与环境准备
第 1 章 全面认识 NumPy
第 2 章 开发环境搭建与验证
第二部分:核心对象 ——ndarray 数组
第 3 章 ndarray 数组基础
第 4 章 数组的形状与维度操作
第四部分:高级应用与数据处理
第 8 章 数组的排序、查找与去重
第 9 章 缺失值与异常值处理
第 10 章 随机数生成与抽样
第 11 章 文件读写与数据交互
第五部分:实战场景与落地应用
第 12 章 数值计算实战
第 13 章 数据分析实战
第六部分:优化进阶与问题解决
第 14 章 NumPy 性能优化
第 15 章 NumPy 进阶扩展
第 16 章 常见问题与解决方案

13.2 时间序列处理

NumPy时间序列处理教程:构建数组、滑动窗口计算与股票趋势分析

NumPy 中文教程

本NumPy教程详细讲解时间序列处理,包括时间序列数组构建、滑动窗口计算移动平均和标准差的方法,并通过股票价格趋势分析的实战示例,帮助新手快速掌握NumPy在时间序列分析中的应用。

推荐工具
PyCharm专业版开发必备

功能强大的Python IDE,提供智能代码补全、代码分析、调试和测试工具,提高Python开发效率。特别适合处理列表等数据结构的开发工作。

了解更多

NumPy时间序列处理:从基础到实战

引言

时间序列数据是按时间顺序排列的数据点,广泛应用于金融、气象、物联网等领域。NumPy作为Python的核心科学计算库,提供了强大的数组处理功能,非常适合时间序列分析。本教程将带你从零开始,学习如何使用NumPy处理时间序列数据,重点包括时间序列数组构建、滑动窗口计算(如移动平均和标准差),并通过实战案例——股票价格趋势分析,巩固所学知识。

时间序列数组构建

在NumPy中,时间序列数据通常表示为数组,其中一维表示时间点,另一维表示数据值。以下是构建时间序列数组的基本步骤。

1. 导入NumPy和其他必要库

首先,确保安装了NumPy。如果处理时间戳,可以结合Python的datetime模块。

import numpy as np
import datetime as dt

2. 创建时间戳数组

使用datetime模块创建时间戳列表,然后转换为NumPy数组。

# 生成日期范围
start_date = dt.datetime(2023, 1, 1)
dates = [start_date + dt.timedelta(days=i) for i in range(10)]  # 10天的日期
# 转换为NumPy数组(通常是对象类型,但可以使用datetime64改进)
时间戳数组 = np.array(dates, dtype='datetime64[D]')  # 使用datetime64提高效率
print(时间戳数组)

3. 创建数值数据数组

数值数据可以代表如股票价格、温度等。

# 示例:生成随机股票价格数据
np.random.seed(42)  # 确保结果可复现
股票价格 = np.random.randn(10) * 10 + 100  # 均值为100,标准差为10的正态分布数据
print(股票价格)

4. 组合成时间序列数组

将时间戳和数值数据组合成一个二维数组或结构数组。常见方法是使用NumPy的record arrays或pandas(但本教程聚焦NumPy)。

# 使用结构化数组
时间序列 = np.array([(时间戳数组[i], 股票价格[i]) for i in range(10)],
                     dtype=[('date', 'datetime64[D]'), ('price', 'float64')])
print(时间序列)

或者,如果你只需要数值数据随时间变化,可以保持为两个一维数组,通过索引关联。

时间序列处理基础

一旦构建了时间序列数组,就可以进行各种操作。

索引和切片

NumPy数组支持基于位置的索引和切片,便于提取特定时间段的数据。

# 提取前5天的价格数据
前五天价格 = 股票价格[:5]
print(前五天价格)

缺失值处理

时间序列数据中常有缺失值。NumPy提供了np.nan表示缺失,可以使用掩码数组处理。

# 示例:模拟缺失值
股票价格_with_nan = 股票价格.copy()
股票价格_with_nan[2] = np.nan  # 假设第3天数据缺失
print(股票价格_with_nan)
# 使用np.isnan检测缺失值
缺失索引 = np.where(np.isnan(股票价格_with_nan))[0]
print(f"缺失值索引: {缺失索引}")

滑动窗口计算:移动平均与标准差

滑动窗口是一种常见的时间序列分析方法,用于平滑数据或计算局部统计量。

1. 滑动窗口概念

滑动窗口将数据划分为重叠或非重叠的子序列,例如,一个窗口大小为3的滑动窗口在数组[1,2,3,4,5]上会生成子数组[1,2,3]、[2,3,4]、[3,4,5]。

2. 计算移动平均

移动平均(Moving Average, MA)通过计算窗口内数据的平均值来平滑时间序列。

使用np.convolve方法

def moving_average(data, window_size):
    """计算简单移动平均"""
    if window_size <= 0 or window_size > len(data):
        raise ValueError("窗口大小必须为正且不超过数据长度")
    # np.convolve用于卷积,通过归一化计算平均
    weights = np.ones(window_size) / window_size
    ma = np.convolve(data, weights, mode='valid')  # mode='valid'避免边界效应
    return ma

# 示例
数据 = np.array([10, 20, 30, 40, 50])
窗口大小 = 3
ma_result = moving_average(数据, 窗口大小)
print(f"移动平均结果: {ma_result}")

使用NumPy 1.20+的sliding_window_view(更高效)

# 确保NumPy版本支持
if hasattr(np.lib.stride_tricks, 'sliding_window_view'):
    def moving_average_sliding(data, window_size):
        windows = np.lib.stride_tricks.sliding_window_view(data, window_size)
        ma = np.mean(windows, axis=1)
        return ma
    ma_sliding = moving_average_sliding(数据, 窗口大小)
    print(f"使用sliding_window_view的移动平均: {ma_sliding}")
else:
    print("您的NumPy版本较低,请升级以使用sliding_window_view。")

3. 计算移动标准差

移动标准差(Moving Standard Deviation)用于衡量数据的波动性。

类似地,使用滑动窗口计算标准差。

def moving_std(data, window_size):
    """计算移动标准差"""
    if window_size <= 0 or window_size > len(data):
        raise ValueError("窗口大小必须为正且不超过数据长度")
    # 使用sliding_window_view(如果可用)
    if hasattr(np.lib.stride_tricks, 'sliding_window_view'):
        windows = np.lib.stride_tricks.sliding_window_view(data, window_size)
        std = np.std(windows, axis=1, ddof=1)  # ddof=1用于样本标准差
    else:
        # 备用方法:使用循环或np.convolve(但标准差计算更复杂)
        std = np.array([np.std(data[i:i+window_size], ddof=1) for i in range(len(data)-window_size+1)])
    return std

std_result = moving_std(数据, 窗口大小)
print(f"移动标准差结果: {std_result}")

4. 边界处理

滑动窗口计算时,边界数据可能不足。常见处理方式包括:

  • 'valid':只计算完整窗口的数据(如上述示例)。
  • 'same':输出大小与输入相同,边界用填充值。
  • 填充数据:如用前值或后值填充。

实战:股票价格趋势分析

现在,我们将应用所学知识分析股票价格趋势。假设我们有某股票过去30天的每日收盘价数据。

步骤1:准备数据

使用NumPy生成模拟数据或加载真实数据(本教程使用模拟数据)。

# 生成模拟股票价格数据
np.random.seed(123)
days = 30
时间戳 = np.arange('2023-01-01', days, dtype='datetime64[D]')  # 30天的时间戳
股票价格 = 100 + np.cumsum(np.random.randn(days) * 2)  # 随机游走模拟价格
print(f"时间戳: {时间戳[:5]}...")
print(f"股票价格(前5天): {股票价格[:5]}")

步骤2:计算移动平均和标准差

使用滑动窗口分析趋势和波动。

窗口大小 = 5  # 例如,5天移动平均
# 计算移动平均
移动平均_价格 = moving_average(股票价格, 窗口大小)
# 计算移动标准差
移动标准差_价格 = moving_std(股票价格, 窗口大小)
print(f"移动平均(前几个值): {移动平均_价格[:5]}")
print(f"移动标准差(前几个值): {移动标准差_价格[:5]}")

步骤3:趋势分析

通过比较原始价格和移动平均,可以识别趋势。

  • 当价格高于移动平均时,可能表示上升趋势。
  • 当价格低于移动平均时,可能表示下降趋势。
  • 移动标准差高表示波动大,风险较高。
# 简单趋势判断
趋势 = []
for i in range(len(移动平均_价格)):
    if 股票价格[i+窗口大小-1] > 移动平均_价格[i]:
        趋势.append("上升")
    else:
        趋势.append("下降")
print(f"趋势判断(示例): {趋势[:5]}")

步骤4:可视化(可选,使用matplotlib)

虽然NumPy不直接绘图,但可以结合matplotlib可视化结果。

# 如果需要可视化,安装matplotlib: pip install matplotlib
import matplotlib.pyplot as plt

plt.figure(figsize=(10, 6))
plt.plot(时间戳[窗口大小-1:], 股票价格[窗口大小-1:], label='原始价格', color='blue')
plt.plot(时间戳[窗口大小-1:], 移动平均_价格, label=f'{窗口_size}天移动平均', color='red')
plt.fill_between(时间戳[窗口大小-1:], 
                 移动平均_价格 - 移动标准差_价格, 
                 移动平均_价格 + 移动标准差_价格, 
                 color='gray', alpha=0.3, label='标准差带')
plt.xlabel('日期')
plt.ylabel('价格')
plt.title('股票价格趋势分析')
plt.legend()
plt.show()

总结与扩展

通过本教程,你学会了:

  1. 构建时间序列数组:使用NumPy和datetime模块创建时间戳和数值数组。
  2. 时间序列处理基础:索引、切片和缺失值处理。
  3. 滑动窗口计算:实现移动平均和移动标准差,使用np.convolvesliding_window_view
  4. 实战应用:在股票价格趋势分析中,利用滑动窗口识别趋势和波动。

扩展学习

  • 高级滑动窗口:探索加权移动平均(如指数移动平均)。
  • 性能优化:对于大数据集,考虑使用NumPy的向量化操作避免循环。
  • 集成其他库:结合pandas进行更复杂的时间序列分析。

NumPy是时间序列分析的强大工具,掌握这些基础后,你可以进一步探索机器学习或深度学习中的时间序列预测。祝你学习愉快!


注意:本教程使用模拟数据,实际应用中请确保数据来源可靠。NumPy版本建议1.20或更高以获得最佳功能支持。

开发工具推荐
Python开发者工具包

包含虚拟环境管理、代码格式化、依赖管理、测试框架等Python开发全流程工具,提高开发效率。特别适合处理复杂数据结构和算法。

获取工具包