如何基于参考标记位置计算Python中的相对值?
问题描述
现有一个包含Item、Pmpp、IsReference、TimeStamp列的表格,需求如下:
- 按
Item分组,以每组中IsReference=1对应的Pmpp值为基准,计算组内其余Pmpp的相对值 - 同理,按
Item分组,以每组中IsReference=1对应的TimeStamp为参考日期,计算组内每条记录与参考日期的日期差
以下是初始实现代码,但存在逻辑问题:
import pandas as pd d = {'Item': ["dmc1", "dmc1", "dmc1", "dmc1", "dmc2", "dmc2", "dmc2", "dmc2"], 'Pmpp': [3, 4, 3, 1, 2, 4, 3, 1], 'IsReference': [0, 1, 0, 0, 1, 0, 0, 0], 'TimeStamp': ["22.02.2023", "25.02.2023", "28.02.2023", "3.03.2023", "24.02.2023", "25.02.2023", "2.03.2023", "5.03.2023"] } df = pd.DataFrame(data = d) # find location of reference ref = df['Pmpp'][df['IsReference'] == 1].values # calculate relative values df['Pmpp_norm'] = df.groupby('Item')['Pmpp'].apply(lambda x: x/ref)
解决方案
步骤说明
- 转换日期格式:先将
TimeStamp列转换为pandas可识别的日期类型,方便后续计算日期差 - 分组提取基准值:按
Item分组后,在每组内提取IsReference=1对应的Pmpp和TimeStamp作为基准 - 计算相对Pmpp值:组内每条记录的
Pmpp除以该组的基准Pmpp - 计算日期差:用每条记录的日期减去组内参考日期,得到天数差
修正后完整代码
import pandas as pd d = {'Item': ["dmc1", "dmc1", "dmc1", "dmc1", "dmc2", "dmc2", "dmc2", "dmc2"], 'Pmpp': [3, 4, 3, 1, 2, 4, 3, 1], 'IsReference': [0, 1, 0, 0, 1, 0, 0, 0], 'TimeStamp': ["22.02.2023", "25.02.2023", "28.02.2023", "3.03.2023", "24.02.2023", "25.02.2023", "2.03.2023", "5.03.2023"] } df = pd.DataFrame(data=d) # 1. 转换TimeStamp为日期格式,指定日期格式匹配输入 df['TimeStamp'] = pd.to_datetime(df['TimeStamp'], format='%d.%m.%Y') # 2. 定义分组处理函数,同时计算基准Pmpp和日期差 def process_group(group): # 获取组内的参考Pmpp值 ref_pmpp = group.loc[group['IsReference'] == 1, 'Pmpp'].iloc[0] # 获取组内的参考日期 ref_date = group.loc[group['IsReference'] == 1, 'TimeStamp'].iloc[0] # 计算相对Pmpp group['Pmpp_norm'] = group['Pmpp'] / ref_pmpp # 计算日期差(天数) group['TimeDiff_days'] = (group['TimeStamp'] - ref_date).dt.days return group # 3. 按Item分组应用处理函数 df = df.groupby('Item').apply(process_group).reset_index(drop=True) print(df)
代码说明
- 初始代码的问题在于全局提取了所有参考Pmpp值,没有按组区分,导致分组计算时基准值错误
- 使用
groupby.apply()在每组内独立提取基准值,确保每组使用自己的参考数据 (group['TimeStamp'] - ref_date).dt.days将时间差转换为整数天数,方便查看
输出结果
Item Pmpp IsReference TimeStamp Pmpp_norm TimeDiff_days 0 dmc1 3 0 2023-02-22 0.75 -3 1 dmc1 4 1 2023-02-25 1.00 0 2 dmc1 3 0 2023-02-28 0.75 3 3 dmc1 1 0 2023-03-03 0.25 6 4 dmc2 2 1 2023-02-24 1.00 0 5 dmc2 4 0 2023-02-25 2.00 1 6 dmc2 3 0 2023-03-02 1.50 6 7 dmc2 1 0 2023-03-05 0.50 9
内容的提问来源于stack exchange,提问作者Przem
相关产品推荐
相关产品推荐

