使用 Pandas 高效获取 DataFrame 历史同期数据

心靈之曲
发布: 2025-10-18 09:02:17
原创
919人浏览过

使用 pandas 高效获取 dataframe 历史同期数据

本教程详细介绍了如何利用 Pandas 库高效地从 DataFrame 中提取指定历史同期的数据,并计算相应的绝对变化量和百分比变化量。通过结合 `pd.DateOffset` 进行日期偏移和 `df.merge` 进行数据合并,我们能够灵活地获取任意前推月份的历史数据,为时间序列分析提供强大的数据准备能力,避免了手动处理带来的复杂性和错误。

引言

在数据分析领域,尤其是进行时间序列数据分析时,经常需要将当前数据与历史同期数据进行比较,例如与上个月、上季度或去年同期的数据进行对比,以洞察趋势、评估绩效或识别异常。Pandas 库提供了强大的数据处理能力,但直接获取精确的历史同期值并计算其变化量,对于初学者而言可能会遇到挑战。本文将提供一个通用的解决方案,通过自定义函数和 Pandas 的核心功能,实现灵活、高效的历史同期数据提取与分析。

挑战与 Pandas .pct_change() 的局限性

Pandas 内置的 .pct_change() 方法可以方便地计算相邻时间点之间的百分比变化。然而,它的主要局限在于只能计算紧邻的或基于固定周期(如 periods=1)的变化,而无法直接获取任意指定月份(如 3 个月前、12 个月前)的精确原始值进行比较。当我们需要获取的是“去年同期”或“上上个月”的具体数值,而非仅仅是其变化率时,就需要更精细的数据处理方法。

核心思路:日期偏移与数据合并

解决此问题的核心策略是:

  1. 日期偏移: 为 DataFrame 中的每个日期计算出其对应的历史同期日期(例如,当前日期减去 N 个月)。
  2. 数据合并: 将原始 DataFrame 与其自身进行合并,通过将当前日期的“历史同期日期”与原始 DataFrame 的“实际日期”进行匹配,从而将历史同期的数据引入到当前行。

实施步骤与代码示例

我们将通过一个具体的 Python 脚本来演示如何实现这一功能。假设我们有一个包含 URL、关键词、流量和日期的数据集,目标是为每个数据点添加其 1 个月前和 12 个月前的关键词和流量数据。

1. 数据准备

首先,我们需要导入必要的库,并加载示例数据。数据加载后,关键步骤是将日期列转换为 Pandas 的日期时间格式,并按日期降序排序,这有助于后续的理解和处理,尽管对于 merge 操作并非严格要求排序。

速创猫AI简历
速创猫AI简历

一键生成高质量简历

速创猫AI简历 149
查看详情 速创猫AI简历
import pandas as pd
import io 

# 示例输入数据
INPUT_CSV = """
URL,Organic Keywords,Organic Traffic,Date
https://www.example-url.com/,1315,11345,20231115
https://www.example-url.com/,1183,5646,20231015
https://www.example-url.com/,869,5095,20230915
https://www.example-url/,925,4574,20230815
https://www.example-url/,899,4580,20230715
https://www.example-url/,1382,5720,20230615
https://www.example-url/,1171,5544,20230515
https://www.example-url/,1079,5041,20230415
https://www.example-url/,734,3855,20230315
https://www.example-url/,853,3455,20230215
https://www.example-url/,840,2343,20230115
https://www.example-url/,325,2318,20221215
https://www.example-url/,156,1981,20221115
https://www.example-url/,166,2059,20221015
https://www.example-url/,124,1977,20220915
https://www.example-url/,98,1919,20220815
https://www.example-url/,167,1796,20220715
https://www.example-url/,140,1596,20220615
https://www.example-url/,168,1493,20220515
https://www.example-url/,171,1058,20220415
https://www.example-url/,141,1735,20220315
https://www.example-url/,129,1836,20220215
https://www.example-url/,141,746,20220115
https://www.example-url/,129,1076,20211215
"""

# 定义常量
INITIAL_COL_REORDER = ['URL', 'Date', 'Organic Keywords', 'Organic Traffic']
METRIC_COLS = ['Organic Keywords', 'Organic Traffic']
DIMENSION_COLS = ['URL'] # 维度列,用于在合并时作为额外的匹配条件
DATE_COL = 'Date'
PERIODS = [1, 3, 12] # 需要计算的历史同期周期(月)

# 读取CSV数据
df = pd.read_csv(io.StringIO(INPUT_CSV))
# 重新排序列,确保关键列在前
df = df[INITIAL_COL_REORDER]
# 将日期列转换为datetime对象
df[DATE_COL] = pd.to_datetime(df[DATE_COL], format='%Y%m%d')
# 按日期降序排序
df = df.sort_values(by=DATE_COL, ascending=False)

print("原始数据(前5行):")
print(df.head())
登录后复制

2. 构建 get_last_period_values 辅助函数

这个函数是实现核心逻辑的关键。它接收 DataFrame、要回溯的月份数、指标列、维度列和日期列作为参数。

def get_last_period_values(df, months_prior, metric_cols, dimension_cols, date_col):
    df_copy = df.copy() # 创建副本以避免修改原始DataFrame

    # 1. 计算历史同期日期
    # 使用 pd.DateOffset(months=months_prior) 从当前日期减去指定月份
    df_copy[f'{date_col}_Prior'] = df_copy[date_col] - pd.DateOffset(months=months_prior)

    # 2. 将原始DataFrame与自身合并
    # left_on: 当前DataFrame中的计算出的历史同期日期
    # right_on: 原始DataFrame中的实际日期
    # 此外,我们还通过 'URL' (dimension_cols) 进行匹配,确保比较的是同一URL的数据
    # suffixes: 用于区分合并后同名列(当前值和历史值)的后缀
    df_copy = df_copy.merge(
        df_copy[[date_col] + dimension_cols + metric_cols], # 右侧DataFrame选择的列
        left_on=[f'{date_col}_Prior'] + dimension_cols, # 左侧合并键
        right_on=[date_col] + dimension_cols, # 右侧合并键
        how='left', # 使用左连接,保留所有当前数据,没有历史数据则填充NaN
        suffixes=('', f'_{months_prior}mo_Prior') # 左侧列无后缀,右侧列添加后缀
    )

    # 3. 清理辅助列
    # 移除用于合并的临时历史日期列以及合并时产生的维度列(因为原始维度列已存在)
    df_copy = df_copy.drop(columns=[f'{date_col}_Prior'] + [col + f'_{months_prior}mo_Prior' for col in dimension_cols])

    # 4. 计算绝对变化量和百分比变化量
    for metric in metric_cols:
        # 绝对变化量:当前值 - 历史值
        df_copy[f'{metric}_{months_prior}mo_Abs_Change'] = df_copy[metric] - df_copy[f'{metric}_{months_prior}mo_Prior']
        # 百分比变化量:(当前值 / 历史值) - 1,并四舍五入到两位小数
        df_copy[f'{metric}_{months_prior}mo_Pct_Change'] = df_copy[metric] / df_copy[f'{metric}_{months_prior}mo_Prior'] - 1
        df_copy[f'{metric}_{months_prior}mo_Pct_Change'] = df_copy[f'{metric}_{months_prior}mo_Pct_Change'].round(2)

    return df_copy
登录后复制

merge 操作详解:

  • left_on=[f'{date_col}_Prior'] + dimension_cols: 这是左侧(当前 DataFrame)用于匹配的键。它包括了我们计算出的历史同期日期和维度列(如 'URL')。
  • right_on=[date_col] + dimension_cols: 这是右侧(原始 DataFrame)用于匹配的键。它包括了原始日期列和维度列。
  • how='left': 确保所有当前数据行都被保留。如果某个日期的历史同期数据不存在,则对应的历史值列将填充 NaN。
  • suffixes=('', f'_{months_prior}mo_Prior'): 当合并导致列名冲突时,Pandas 会自动添加后缀。这里我们指定左侧(当前数据)列名不变,右侧(历史数据)列名添加 _Xmo_Prior 后缀。例如,Organic Keywords 变成 Organic Keywords_1mo_Prior。需要注意的是,如果 date_col 也被选入右侧的列中,且与左侧的 date_col 冲突,它也会被加上后缀,即生成 Date_Xmo_Prior。

3. 整合多个周期计算的函数

为了方便地计算多个历史同期周期的数据,我们可以再封装一个函数。

def get_period_values(df, periods, metric_cols, dimension_cols, date_col):
    df_copy = df.copy()
    for period in periods:
        df_copy = get_last_period_values(df_copy, period, metric_cols, dimension_cols, date_col)
    return df_copy
登录后复制

4. 主脚本执行

现在,我们可以将所有部分组合起来,执行主脚本。

if __name__ == '__main__':
    # 已经完成了数据加载和预处理
    # df = pd.read_csv(io.StringIO(INPUT_CSV))
    # df = df[INITIAL_COL_REORDER]
    # df[DATE_COL] = pd.to_datetime(df[DATE_COL], format='%Y%m%d')
    # df = df.sort_values(by=DATE_COL, ascending=False)

    # 调用整合函数计算所有指定周期的历史数据
    df_final = get_period_values(df, PERIODS, METRIC_COLS, DIMENSION_COLS, DATE_COL)

    # 显示最终结果
    print("\n最终结果DataFrame(前5行):")
    print(df_final.head())

    # 打印所有列,检查输出
    print("\n最终结果DataFrame所有列:")
    print(df_final.columns.tolist())
登录后复制

运行上述代码,你将得到一个包含原始数据、1个月前、3个月前、12个月前的关键词和流量数据,以及它们对应的绝对变化和百分比变化的完整 DataFrame。

示例输出(部分)

最终结果DataFrame(前5行):
                       URL       Date  Organic Keywords  Organic Traffic  \
0  https://www.example-url/ 2023-11-15              1315            11345   
1  https://www.example-url/ 2023-10-15              1183             5646   
2  https://www.example-url/ 2023-09-15               869             5095   
3  https://www.example-url/ 2023-08-15               925             4574   
4  https://www.example-url/ 2023-07-15               899             4580   

   Date_1mo_Prior  Organic Keywords_1mo_Prior  Organic Traffic_1mo_Prior  \
0      2023-10-15                      1183.0                     5646.0   
1      2023-09-15                       869.0                     5095.0   
2      2023-08-15                       925.0                     4574.0   
3      2023-07-15                       899.0                     4580.0   
4      2023-06-15                      1382.0                     5720.0   

   Organic Keywords_1mo_Abs_Change  Organic Keywords_1mo_Pct_Change  \
0                            132.0                             0.11   
1                            314.0                             0.36   
2                           -56.0                            -0.06   
3                            26.0                             0.00   
4                           -483.0                            -0.35   

   Organic Traffic_1mo_Abs_Change  Organic Traffic_1mo_Pct_Change  \
0                          5699.0                            1.01   
1                           551.0                            0.11   
2                           521.0                            0.11   
3                            -6.0                            0.00   
4                         -1140.0                           -0.20   

   Date_3mo_Prior  Organic Keywords_3mo_Prior  Organic Traffic_3mo_Prior  \
0      2023-08-15                       925.0                     4574.0   
1      2023-07-15                       899.0                     4580.0   
2      2023-06-15                      1382.0                     5720.0   
3      2023-05-15                      1171.0                     5544.0   
4      2023-04-15                      1079.0                     5041.0   

   Organic Keywords_3mo_Abs_Change  Organic Keywords_3mo_Pct_Change  \
0                            390.0                             0.42   
1                            284.0                             0.32   
2                           -513.0                            -0.37   
3                           -246.0                            -0.21   
4                           -180.0                            -0.17   

   Organic
登录后复制

以上就是使用 Pandas 高效获取 DataFrame 历史同期数据的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号