15、数据重塑、整理与时间序列分析

数据重塑、整理与时间序列分析

数据重塑与整理

准备工作

使用已熟悉的 academic_df 数据框进行操作。

重塑技术应用

  1. 按列值分区数据框 :使用 .partition_by() 方法将数据框按列值划分为多个独立的数据框。
academic_df.partition_by('academic_year')

此代码会按 academic_year 列的值对数据框进行分区。

  1. 转置数据框 :使用 .transpose() 方法翻转数据框的行和列。
academic_df.transpose(include_header=True)
  1. 将列值重塑为列表 :使用 .reshape() 方法将列值转换为数组。
(
    academic_df
    .select(
        pl.col('academic_year', 'students').reshape((1, 5))
    )
)

方法原理

  • .partition_by() 方法:可返回字典或数据框形式的结果,还能指定多个列进行数据分组。
  • .transpose() 方法:借助 header_name column_names 参数可指定表头和列名。
  • .reshape() 方法:将列值转换为数组,通过元组指定所需形状,元组的第一个值为行数,第二个值为列表中的元素数。
注意事项

.partition_by() .transpose() 方法仅适用于数据框, .reshape() 方法仅适用于列或系列对象。

时间序列分析

技术要求

  1. 安装 Polars 库:
pip install polars
  1. 导入 Polars 库:
import polars as pl
  1. 安装 hvplot 库:
pip install hvplot
  1. 下载数据集:使用历史每小时天气数据集,可从 GitHub 仓库 下载。
  2. 读取数据集为 LazyFrame
lf = pl.scan_csv('../data/toronto_weather.csv')
  1. 查看数据集前五行:
lf.head().collect()
  1. 温度单位转换:将温度从开尔文转换为摄氏度。
lf = lf.with_columns(pl.col('temperature') - 273.15)
lf.head().collect()

处理日期和时间

操作步骤
  1. 读取时转换数据类型 :若源数据的日期、日期时间或时间列为字符串类型,可使用 try_parse_date 参数在读取时进行转换。
lf_date_parsed = pl.scan_csv('../data/toronto_weather.csv', try_parse_dates=True)
lf_date_parsed.head().collect()

可使用 .schema .dtypes 属性检查列的数据类型:

lf_date_parsed.collect_schema(),
lf_date_parsed.collect_schema().dtypes()
  1. 读取后转换数据类型
lf = lf.with_columns(pl.col('datetime').str.to_datetime())
lf.head().collect()
  1. 提取日期特征 :从 datetime 列中提取时间、日、周、月和年等特征。
(
    lf
    .select(
        'datetime',
        pl.col('datetime').dt.year().alias('year'),
        pl.col('datetime').dt.month().alias('month'),
        pl.col('datetime').dt.day().alias('day'),
        pl.col('datetime').dt.time().alias('time')
    )
    .head().collect()
)
  1. 按日期和时间属性过滤
from datetime import datetime
filtered_lf = (
    lf
    .filter(
        pl.col('datetime').dt.date().is_between(
            datetime(2017, 1, 1), datetime(2017, 12, 31)
        ),
        pl.col('datetime').dt.hour() < 12
    )
)
filtered_lf.head().collect()

检查过滤结果:

(
    filtered_lf
    .select(
        pl.col('datetime').dt.year().unique()
        .implode()
        .list.len()
        .alias('year_cnt'),
        pl.col('datetime').dt.hour().unique()
        .implode()
        .list.len()
        .alias('hour_cnt')
    )
    .head()
    .collect()
)
  1. 转换和替换时区
time_zones_lf = (
    lf
    .select(
        'datetime',
        pl.col('datetime').dt.replace_time_zone('America/Toronto')
        .alias('replaced_time_zone_toronto'),
        pl.col('datetime').dt.convert_time_zone('America/Toronto')
        .alias('converted_time_zone_toronto')
    )
)
time_zones_lf.head().collect()
原理说明
  • dt 命名空间:提供多种处理日期和时间属性的方法。
  • 数据类型转换:读取时和读取后均可进行数据类型转换,如使用 .str.strptime() 方法将字符串列转换为日期时间列。
  • 日期范围指定: .is_between() 方法可方便指定日期范围,Python 的 Datetime 对象可用于过滤日期和时间属性。
  • 时区处理: .dt.replace_time_zone() 方法仅分配或重置列的时区, .dt.convert_time_zone() 方法会修改日期时间值。
额外功能

使用 pl.duration() 函数偏移日期和时间属性:

(
    lf
    .select(
        'datetime',
        (pl.col('datetime') - pl.duration(weeks=5)).alias('minus_5weeks'),
        (pl.col('datetime') + pl.duration(milliseconds=5)).alias('plus_5ms')
    )
    .head()
    .collect()
)

应用滚动窗口计算

操作步骤
  1. 计算滚动平均值 :使用 .rolling_mean() 方法计算温度的滚动平均值。
(
    lf
    .select(
        'datetime',
        'temperature',
        pl.col('temperature').rolling_mean(3).alias('3hr_rolling_avg')
    )
    .head()
    .collect()
)
  1. 按天聚合温度
daily_avg_temperature_lf = (
    lf
    .select(
        pl.col('datetime').dt.date().alias('date'),
        'temperature'
    )
    .group_by('date', maintain_order=True)
    .agg(
        pl.col('temperature').mean().alias('daily_avg_temp')
    )
)
daily_avg_temperature_lf.head().collect()
  1. 计算滚动聚合值
(
    daily_avg_temperature_lf
    .select(
        'date',
        'daily_avg_temp',
        pl.col('daily_avg_temp').rolling_mean(3).alias('3day_rolling_avg'),
        pl.col('daily_avg_temp').rolling_min(3).alias('3day_rolling_min'),
        pl.col('daily_avg_temp').rolling_max(3).alias('3day_rolling_max')
    )
    .head()
    .collect()
)
  1. 使用 .rolling() 方法
(
    daily_avg_temperature_lf
    .set_sorted('date')
    .select(
        'date',
        'daily_avg_temp',
        pl.col('daily_avg_temp').rolling_mean(3).alias('3day_rolling_avg'),
        pl.col('daily_avg_temp').rolling_mean(
            window_size=3,
            min_periods=1
        )
        .alias('3day_rolling_avg2'),
        pl.col('daily_avg_temp').mean().rolling(
            index_column='date',
            period='3d',
            closed='right'
        )
        .alias('3day_rolling_avg3')
    )
    .head(10)
    .collect()
)
  1. 使用 .rolling() 数据框方法 :若结果仅包含滚动计算,可使用该方法缓存窗口大小计算。
(
    daily_avg_temperature_lf
    .set_sorted('date')
    .rolling(
        'date',
        period='3d'
    )
    .agg(
        pl.col('daily_avg_temp'),
        pl.col('daily_avg_temp').mean().alias('3day_rolling_avg'),
        pl.col('daily_avg_temp').min().alias('3day_rolling_min'),
        pl.col('daily_avg_temp').max().alias('3day_rolling_max'),
    )
    .head(10)
    .collect()
)
  1. 可视化数据 :使用 Polars 的内置绘图功能可视化每日平均温度和 60 天滚动平均值。
(
    daily_avg_temperature_lf
    .select(
        'date',
        'daily_avg_temp',
        pl.col('daily_avg_temp').rolling_mean(60).alias('60day_rolling_avg')
    )
    .collect()
    .plot.line(
        x='date',
        y=['daily_avg_temp', '60day_rolling_avg'],
        color=['skyblue', 'gray'],
        width=800,
        height=400
    )
    .opts(legend_position='bottom_right')
)
原理说明
  • 内置方法:如 .rolling_mean() .rolling_min() .rolling_max() 等方法可进行滚动计算,还有 .rolling_var() .rolling_std() 等更多方法。
  • .rolling() 方法:更灵活,可使用任何指定表达式进行滚动计算。
  • 数据框方法: .rolling() 数据框方法适用于结果仅包含滚动计算的情况,可提高效率。
注意事项
  • 滚动计算方法:在数据框/ LazyFrame 级别和表达式级别使用的 .rolling() 方法都要求时间列已排序,可使用 .set_sorted() .sort() 方法进行排序。
  • 可视化功能: Polars 的内置绘图功能基于 hvplot 库,需安装该库才能使用。
自定义滚动计算

使用 .rolling_map() 方法接受用户定义的函数进行自定义滚动计算:

def get_range(nums):
    min_num = min(nums)
    max_num = max(nums)
    range = max(nums) - min(nums)
    return range

(
    daily_avg_temperature_lf
    .with_columns(
        pl.col('daily_avg_temp').rolling_map(get_range, window_size=3).alias('3day_rolling_range')
    )
    .head()
    .collect()
)

可视化自定义滚动计算结果:

(
    daily_avg_temperature_lf
    .with_columns(
        pl.col('daily_avg_temp').rolling_map(get_range, window_size=3).alias('3day_rolling_range')
    )
    .collect()
    .plot.line(
        x='date',
        y=['daily_avg_temp', '3day_rolling_range'],
        color=['skyblue', 'gray'],
        width=800,
        height=400
    )
    .opts(legend_position='bottom_right')
)
注意事项

.rolling_map() 方法速度较慢,仅在无法使用内置方法实现逻辑时使用。

流程图

graph LR
    A[读取数据集] --> B[数据预处理]
    B --> C[处理日期和时间]
    C --> D[应用滚动窗口计算]
    D --> E[可视化数据]

表格总结

操作类型 方法 示例代码
数据重塑 .partition_by() academic_df.partition_by('academic_year')
数据重塑 .transpose() academic_df.transpose(include_header=True)
数据重塑 .reshape() academic_df.select(pl.col('academic_year', 'students').reshape((1, 5)))
时间序列处理 try_parse_date pl.scan_csv('../data/toronto_weather.csv', try_parse_dates=True)
时间序列处理 .str.to_datetime() lf.with_columns(pl.col('datetime').str.to_datetime())
滚动计算 .rolling_mean() pl.col('temperature').rolling_mean(3).alias('3hr_rolling_avg')
滚动计算 .rolling() pl.col('daily_avg_temp').mean().rolling(index_column='date', period='3d', closed='right')
自定义滚动计算 .rolling_map() pl.col('daily_avg_temp').rolling_map(get_range, window_size=3).alias('3day_rolling_range')

重采样技术

重采样是时间序列分析中的重要技术,它可以将时间序列数据从一个频率转换为另一个频率。以下是使用 Polars 进行重采样的操作步骤:

操作步骤
  1. 按小时重采样 :将数据按小时进行重采样,并计算每小时的平均温度。
hourly_resampled_lf = (
    lf
    .select(
        pl.col('datetime').dt.truncate('1h').alias('hour'),
        'temperature'
    )
    .group_by('hour', maintain_order=True)
    .agg(
        pl.col('temperature').mean().alias('hourly_avg_temp')
    )
)
hourly_resampled_lf.head().collect()
  1. 按天重采样 :将数据按天进行重采样,并计算每天的平均温度。
daily_resampled_lf = (
    lf
    .select(
        pl.col('datetime').dt.truncate('1d').alias('day'),
        'temperature'
    )
    .group_by('day', maintain_order=True)
    .agg(
        pl.col('temperature').mean().alias('daily_avg_temp')
    )
)
daily_resampled_lf.head().collect()
原理说明
  • dt.truncate() 方法:用于将日期时间列截断到指定的时间间隔,如小时、天等。
  • group_by() agg() 方法:结合使用可以对截断后的时间列进行分组,并计算每组的聚合值。

时间序列预测

时间序列预测是根据历史数据预测未来值的过程。这里将介绍如何使用 functime 库进行时间序列预测。

操作步骤
  1. 安装 functime
pip install functime
  1. 准备数据
# 假设我们使用按天重采样后的数据
forecast_data = daily_resampled_lf.collect()
  1. 进行预测
from functime.forecasting import AutoARIMA

# 创建预测模型
model = AutoARIMA()

# 拟合模型并进行预测
forecast = model.fit_predict(forecast_data, h=30)  # 预测未来 30 天的数据
print(forecast)
原理说明
  • AutoARIMA 模型:是一种自动选择 ARIMA 模型参数的方法,它可以根据数据的特征自动选择最优的模型参数。
  • fit_predict() 方法:用于拟合模型并进行预测, h 参数指定了预测的未来时间步数。

总结

时间序列分析在数据分析和预测中具有重要的应用价值。通过 Polars 库,我们可以方便地处理日期和时间数据,进行滚动窗口计算、重采样等操作。同时,结合 functime 库,我们可以进行时间序列预测,为未来的决策提供支持。

表格总结

操作类型 方法 示例代码
重采样 dt.truncate() pl.col('datetime').dt.truncate('1h').alias('hour')
重采样 group_by() agg() lf.group_by('hour', maintain_order=True).agg(pl.col('temperature').mean().alias('hourly_avg_temp'))
时间序列预测 AutoARIMA model = AutoARIMA(); forecast = model.fit_predict(forecast_data, h=30)

流程图

graph LR
    A[读取数据集] --> B[数据预处理]
    B --> C[处理日期和时间]
    C --> D[应用滚动窗口计算]
    D --> E[重采样技术]
    E --> F[时间序列预测]
    F --> G[可视化结果]
注意事项
  • 在进行滚动计算和重采样时,要确保时间列已排序,否则可能会得到错误的结果。
  • 使用 functime 库进行时间序列预测时,要根据数据的特点选择合适的模型和参数。
  • 对于自定义滚动计算, .rolling_map() 方法速度较慢,尽量使用内置方法。

通过以上的操作和分析,我们可以更好地理解和处理时间序列数据,为实际应用提供有力的支持。

内容概要:本文是《目标检测入门指南》系列的第二部分,重点介绍用于图像分类的经典卷积神经网络(CNN)架构及其在目标检测中的基础作用。文章详细讲解了卷积操作的基本原理,并以AlexNet、VGG和ResNet为例,阐述了不同CNN模型的结构特点创新点,如深层网络设计、小滤波器堆叠和残差连接机制。同时介绍了目标检测常用的评估指标mAP(平均精度均值),解释了其计算方式和意义。此外,文章还回顾了传统的可变形部件模型(DPM),分析其基于根滤波器、部件滤波器和空间形变代价的检测机制,并指出DPM可通过展开推理过程转化为等效的CNN结构。最后,介绍了Overfeat模型,作为首个将分类、定位检测统一于CNN框架的先驱工作,展示了如何通过滑动窗口进行多尺度分类并结合回归器预测边界框。; 适合人群:具备一定计算机视觉和深度学习基础,从事或学习图像识别、目标检测相关方向的研发人员学生;适合希望理解经典CNN模型演进及目标检测早期发展脉络的技术爱好者。; 使用场景及目标:①理解CNN在图像分类中的核心架构演变及其对后续目标检测模型的影响;②掌握mAP等关键评估指标的含义计算方法;③了解DPMOverfeat的设计思想,为深入学习R-CNN系列等现代检测器打下理论基础。; 阅读建议:此资源以综述形式串联多个经典模型,建议结合原文图表参考文献进行延伸阅读,并通过复现典型模型结构加深对卷积、池化、残差连接等操作的理解,从而建立从传统方法到深度学习的完整认知链条。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值