如何基于小DataFrame的时间为Pandas主DataFrame添加新列?
解决方案
向量化实现思路
核心是通过numpy广播机制批量判断每个时间点的活跃值,再按激活时间优先级筛选出目标值,全程避免循环,保证效率。
代码实现
1. 加载数据
直接构造DataFrame(替代原链接加载,避免外部依赖):
import pandas as pd import numpy as np # 主数据 main_df = pd.DataFrame({ 'time': [0, 1, 2, 3, 4, 5, 6], 'value': [10, 20, 35, 30, 40, 40, 60] }) # 激活/停用规则数据 active_rules = pd.DataFrame({ 'value': [20, 30], 'activatedTime': [1, 3], 'deactivatedTime': [5, 4] })
2. 按激活时间降序排序规则
确保最新激活的规则优先级最高,后续筛选时会优先匹配:
# 按激活时间从晚到早排序 sorted_rules = active_rules.sort_values('activatedTime', ascending=False)
3. 向量化判断每个时间点的活跃状态
利用广播生成布尔矩阵,标记每个时间点对应规则是否处于活跃区间:
# 提取主时间序列(转为二维数组用于广播) main_times = main_df['time'].values[:, np.newaxis] # 提取排序后的规则时间区间和对应值 act_times = sorted_rules['activatedTime'].values deact_times = sorted_rules['deactivatedTime'].values rule_values = sorted_rules['value'].values # 生成活跃状态矩阵:shape=(主时间点数, 规则数) is_active = (main_times >= act_times) & (main_times <= deact_times)
4. 筛选每个时间点的目标活跃值
通过argmax定位每个时间点第一个活跃的规则(因规则已排序,第一个即为最近激活的),无活跃值则设为NaN:
# 找到每个时间点第一个活跃规则的索引 first_active_idx = np.argmax(is_active, axis=1) # 将无活跃规则的时间点索引设为-1 first_active_idx[~is_active.any(axis=1)] = -1 # 映射得到recentActive列 main_df['recentActive'] = np.where(first_active_idx != -1, rule_values[first_active_idx], np.nan)
5. 验证结果
运行后得到的main_df与预期一致:
time value recentActive 0 0 10 NaN 1 1 20 20.0 2 2 35 20.0 3 3 30 30.0 4 4 40 30.0 5 5 40 20.0 6 6 60 NaN
关键说明
- 全程使用numpy向量化操作,比循环实现效率提升显著,适合处理大规模数据集;
- 规则排序保证了"最近激活"的优先级,符合需求逻辑;
- 广播机制批量处理时间区间判断,避免逐行遍历。
内容的提问来源于stack exchange,提问作者mwind
相关产品推荐
相关产品推荐

