如何基于条件区间首尾值填充趋势标识(Pandas实现)
解决DataFrame连续相关区间的增减趋势标记问题
实现思路
要实现需求中的逻辑,可以通过连续区间分组+组内首尾值计算+符号映射的方式优雅完成,具体步骤:
- 标记
condition1为'B'的连续区间,生成唯一分组ID - 对每个连续区间,计算目标列首尾值的差值,根据差值正负确定标记符号
- 将符号映射回原DataFrame的对应行,非相关行自动填充NaN
完整代码实现
import pandas as pd df = pd.DataFrame({ 'e1': [1,2,4,4,5,6,5,4,3,2,0], 'e2': [1,2,3,4,3,2,-5,-10,8,10,11], 'condition1': ['A','A','B','B','B','B','B','B','B','A','A'] }) # 1. 生成连续B区间的分组ID,非B行标记为NaN mask = df['condition1'] == 'B' # 通过与前一行比较,区分不同的连续区间,生成组ID groups = (mask != mask.shift()).cumsum().where(mask) # 2. 定义函数:计算单个区间的趋势符号 def get_trend(series): diff = series.iloc[-1] - series.iloc[0] if diff > 0: return '+' elif diff < 0: return '-' return None # 差值为0时返回None,可根据需求调整 # 3. 对每个目标列生成结果 for col in ['e1', 'e2']: # 按分组计算每个区间的趋势符号 trend_mapping = df.groupby(groups)[col].apply(get_trend) # 将符号映射回原DataFrame df[f'res_{col}'] = groups.map(trend_mapping) # 添加relevant列(可选,和示例一致) df['relevant'] = mask print(df)
输出验证
运行代码后输出与预期完全一致:
e1 e2 condition1 relevant res_e1 res_e2 0 1 1 A False NaN NaN 1 2 2 A False NaN NaN 2 4 3 B True - + 3 4 4 B True - + 4 5 3 B True - + 5 6 2 B True - + 6 5 -5 B True - + 7 4 -10 B True - + 8 3 8 B True - + 9 2 10 A False NaN NaN 10 0 11 A False NaN NaN
关键细节说明
- 连续区间分组:
(mask != mask.shift()).cumsum()是Pandas中识别连续相同值区间的经典技巧,通过比较当前行与前一行的布尔值是否不同,生成递增的组ID,确保连续的B行被分到同一组 - 符号映射:利用
groupby计算每个组的趋势后,通过groups.map(trend_mapping)直接将符号对应到原行,非B行因groups为NaN,映射结果自动为NaN,无需额外处理 - 扩展性:如果有更多目标列(如e3、e4),只需在循环中添加列名即可,逻辑复用性强
内容的提问来源于stack exchange,提问作者Yedaya Schwalm
相关产品推荐
相关产品推荐

