如何在DataFrame中根据特定TEXT值计算TIME列指定行差值生成delay列
给DataFrame添加
delay列的实现方案 需求明确
我有一个DataFrame df,要新增一列delay,规则如下:
- 当
TEXT列值为P_S1时,delay= 该行TIME值 - 同ID分组下最近的TEXT_W1对应的TIME值 - 当
TEXT列值为P_S2时,delay= 该行TIME值 - 同ID分组下最近的TEXT_W2对应的TIME值 - 其他情况
delay填充为NA - 实际数据集包含更多
P_Sn与TEXT_Wn的配对组
代码实现
场景1:同组内基准行多次出现,取最近值
如果同一个ID下会重复出现TEXT_Wn行,需要取P_Sn行之前最近的基准值,用以下代码:
import pandas as pd # 定义配对关系,可按需扩展更多组 pair_map = { 'P_S1': 'TEXT_W1', 'P_S2': 'TEXT_W2' # 示例扩展:'P_S3': 'TEXT_W3' } def process_single_group(group): # 初始化delay列为NA group['delay'] = pd.NA for target_text, base_text in pair_map.items(): # 筛选当前组内的所有基准行 base_records = group[group['TEXT'] == base_text] if base_records.empty: continue # 筛选当前组内的所有目标行 target_indices = group[group['TEXT'] == target_text].index for idx in target_indices: # 取目标行之前的最后一条基准行的TIME值 prior_base_records = base_records[base_records.index < idx] if not prior_base_records.empty: latest_base_time = prior_base_records['TIME'].iloc[-1] group.loc[idx, 'delay'] = group.loc[idx, 'TIME'] - latest_base_time return group # 按ID分组处理整个DataFrame df = df.groupby('ID').apply(process_single_group).reset_index(drop=True)
场景2:同组内基准行仅出现一次
如果每个ID下每个TEXT_Wn只出现一次,直接取该唯一基准值计算,效率更高:
import pandas as pd pair_map = { 'P_S1': 'TEXT_W1', 'P_S2': 'TEXT_W2' } # 遍历每个配对组 for target_text, base_text in pair_map.items(): # 按ID分组,提取每组中base_text对应的TIME值并广播到整组 base_time = df.groupby('ID')['TIME'].transform( lambda x: x[df['TEXT'] == base_text].iloc[0] if len(x[df['TEXT'] == base_text]) > 0 else pd.NA ) # 仅在目标行计算差值 df.loc[df['TEXT'] == target_text, 'delay'] = df['TIME'] - base_time # 非目标行的delay保持NA df['delay'] = df['delay'].where(df['TEXT'].isin(pair_map.keys()), pd.NA)
补充说明
- 两种方法都支持扩展:只需在
pair_map字典中添加新的P_Sn与TEXT_Wn配对,即可自动处理更多组的计算。 - 场景1逻辑更灵活,适配基准行重复出现的情况;场景2执行效率更高,适合基准行唯一的场景。
内容的提问来源于stack exchange,提问作者dede
相关产品推荐
相关产品推荐

