基于DataFrame分组筛选基准值并执行列除法生成新列的Python代码需求
Python实现DataFrame分组基准值计算与D列生成
需求说明
给定DataFrame,需完成以下操作:
- 按A列的唯一值(如C1、V2)分组
- 对每个分组的C列:
- 提取该分组最后两个C值作为候选基准值
- 将两个候选值与分组内其余C值对比,选出与其余值最接近的那个作为基准值(示例中C1分组的基准值为12.33,V2分组为36.23)
- 生成D列:
- 分组内除最后一行外,所有行的C值除以基准值
- 分组最后一行的D列设为
-
示例DataFrame
| A | B | C | D |
|---|---|---|---|
| C1 | b1 | 10.2 | (10.2/12.33) |
| C1 | b2 | 11.2 | (11.2/12.33) |
| C1 | b3 | 13.12 | (13.12/12.33) |
| C1 | b4 | 11.90 | (11.90/12.33) |
| C1 | b5 | 12.33 | (12.33/12.33) |
| C1 | b6 | 43.90 | - |
| V2 | b1 | 54.08 | (54.08/36.23) |
| V2 | b2 | 42.99 | (42.99/36.23) |
| V2 | b3 | 43.65 | (43.65/36.23) |
| V2 | b4 | 36.23 | (36.23/36.23) |
| V2 | b5 | 12.23 | - |
代码实现
import pandas as pd import numpy as np def process_group(group): c_vals = group['C'].values # 提取最后两个候选基准值 last_two = c_vals[-2:] # 分组内其余C值 rest_vals = c_vals[:-2] # 计算候选值与其余值的平均绝对误差,选误差最小的为基准值 if len(rest_vals) == 0: base_val = last_two[0] else: mae_candidate1 = np.mean(np.abs(rest_vals - last_two[0])) mae_candidate2 = np.mean(np.abs(rest_vals - last_two[1])) base_val = last_two[0] if mae_candidate1 <= mae_candidate2 else last_two[1] # 生成D列:非最后一行用C/基准值,最后一行设为'-' # 若需要示例中的字符串格式,替换下面一行为注释内的代码 group['D'] = np.where(group.index != group.index[-1], group['C'] / base_val, '-') # group['D'] = np.where( # group.index != group.index[-1], # group['C'].apply(lambda x: f"({x}/{base_val:.2f})"), # '-' # ) return group # 构造示例数据 data = { 'A': ['C1', 'C1', 'C1', 'C1', 'C1', 'C1', 'V2', 'V2', 'V2', 'V2', 'V2'], 'B': ['b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b1', 'b2', 'b3', 'b4', 'b5'], 'C': [10.2, 11.2, 13.12, 11.90, 12.33, 43.90, 54.08, 42.99, 43.65, 36.23, 12.23] } df = pd.DataFrame(data) # 分组处理 df_result = df.groupby('A', group_keys=False).apply(process_group) print(df_result)
代码说明
- 用
groupby('A')按A列分组,group_keys=False避免额外添加分组索引 - 通过**平均绝对误差(MAE)**判断候选基准值与其余值的接近程度,MAE越小则越接近
- 用
np.where快速区分分组内最后一行和其他行,生成对应D列值 - 代码提供两种D列格式:数值计算结果和示例中的字符串格式,可按需切换
内容的提问来源于stack exchange,提问作者zhhJll
相关产品推荐
相关产品推荐

