
本教程详细介绍了如何利用 Pandas 库高效地从 DataFrame 中提取指定历史同期的数据,并计算相应的绝对变化量和百分比变化量。通过结合 `pd.DateOffset` 进行日期偏移和 `df.merge` 进行数据合并,我们能够灵活地获取任意前推月份的历史数据,为时间序列分析提供强大的数据准备能力,避免了手动处理带来的复杂性和错误。
在数据分析领域,尤其是进行时间序列数据分析时,经常需要将当前数据与历史同期数据进行比较,例如与上个月、上季度或去年同期的数据进行对比,以洞察趋势、评估绩效或识别异常。Pandas 库提供了强大的数据处理能力,但直接获取精确的历史同期值并计算其变化量,对于初学者而言可能会遇到挑战。本文将提供一个通用的解决方案,通过自定义函数和 Pandas 的核心功能,实现灵活、高效的历史同期数据提取与分析。
Pandas 内置的 .pct_change() 方法可以方便地计算相邻时间点之间的百分比变化。然而,它的主要局限在于只能计算紧邻的或基于固定周期(如 periods=1)的变化,而无法直接获取任意指定月份(如 3 个月前、12 个月前)的精确原始值进行比较。当我们需要获取的是“去年同期”或“上上个月”的具体数值,而非仅仅是其变化率时,就需要更精细的数据处理方法。
解决此问题的核心策略是:
我们将通过一个具体的 Python 脚本来演示如何实现这一功能。假设我们有一个包含 URL、关键词、流量和日期的数据集,目标是为每个数据点添加其 1 个月前和 12 个月前的关键词和流量数据。
首先,我们需要导入必要的库,并加载示例数据。数据加载后,关键步骤是将日期列转换为 Pandas 的日期时间格式,并按日期降序排序,这有助于后续的理解和处理,尽管对于 merge 操作并非严格要求排序。
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())这个函数是实现核心逻辑的关键。它接收 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_copymerge 操作详解:
为了方便地计算多个历史同期周期的数据,我们可以再封装一个函数。
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现在,我们可以将所有部分组合起来,执行主脚本。
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中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号