在Pandas中基于不同基准年计算时间差值的实现方法
问题描述
给定如下Pandas数据集:
d = {'origin': ['a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'], 'destination': ['b', 'b', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'c', 'c', 'c'], 'year': [2000, 2001, 2002, 2003, 2004, 2005, 2000, 2001, 2002, 2003, 2004, 2005], 'value': [10, 17, 22, 7, 8, 14, 10, 2, 5, 7, 78, 23] } data_frame = pd.DataFrame(data=d) data_frame.set_index(['origin', 'destination'], inplace=True)
需要针对每个origin-destination索引对,基于value列计算差值:
- 2000-2002年(含2000年):用当年
value减去2000年对应值作为差值; - 2003年及以后:切换为用当年
value减去2003年对应值作为差值。
最终期望得到包含diff列的数据集如下:
d = {'origin': ['a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'], 'destination': ['b', 'b', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'c', 'c', 'c'], 'year': [2000, 2001, 2002, 2003, 2004, 2005, 2000, 2001, 2002, 2003, 2004, 2005], 'value': [10, 17, 22, 7, 8, 14, 10, 2, 5, 7, 78, 23], 'diff': [0, 7, 12, 0, 1, 7, 0, -8, -5, 0, 71, 16] } data_frame = pd.DataFrame(data=d) data_frame.set_index(['origin', 'destination'], inplace=True)
实现方案
可以通过分组提取基准值、条件判断计算差值的方式实现,代码如下:
import pandas as pd import numpy as np # 1. 构建原始数据集 d = {'origin': ['a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'], 'destination': ['b', 'b', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'c', 'c', 'c'], 'year': [2000, 2001, 2002, 2003, 2004, 2005, 2000, 2001, 2002, 2003, 2004, 2005], 'value': [10, 17, 22, 7, 8, 14, 10, 2, 5, 7, 78, 23] } data_frame = pd.DataFrame(data=d) data_frame.set_index(['origin', 'destination'], inplace=True) # 2. 按索引分组,提取每个组的2000年、2003年基准值 base_values = data_frame.groupby(level=['origin', 'destination'])['value'].agg( base_2000=lambda x: x[data_frame.loc[x.index, 'year'] == 2000].iloc[0], base_2003=lambda x: x[data_frame.loc[x.index, 'year'] == 2003].iloc[0] ) # 3. 将基准值合并回原数据集 data_frame = data_frame.merge(base_values, left_index=True, right_index=True) # 4. 根据年份条件计算diff列 data_frame['diff'] = np.where( data_frame['year'] <= 2002, data_frame['value'] - data_frame['base_2000'], data_frame['value'] - data_frame['base_2003'] ) # 5. 移除临时基准列(可选操作) data_frame.drop(['base_2000', 'base_2003'], axis=1, inplace=True) # 查看结果 print(data_frame)
逻辑说明
- 分组提取基准:通过
groupby按origin-destination索引分组,分别提取每个组2000年和2003年的value作为计算差值的基准; - 合并基准值:将每个组的基准值关联到原数据的每一行,确保每行都能获取到对应的基准;
- 条件计算差值:使用
np.where判断年份,≤2002的行用2000年基准计算,≥2003的行用2003年基准计算; - 清理临时列:可选移除用于计算的基准列,让数据集更简洁。
运行代码后得到的结果与期望的目标数据集完全一致。
内容的提问来源于stack exchange,提问作者Avto Abashishvili
相关产品推荐
相关产品推荐

