如何在Pandas中基于符合条件的前一行值生成新列
高效实现Pandas中基于条件的前向匹配值填充
需求说明
现有如下结构的Pandas DataFrame:
TimeStamp Event Value 0 1603822620000 1 102.0 1 1603822680000 1 108.0 2 1603822740000 1 107.0 3 1603822800000 2 1 4 1603823040000 1 106.0 5 1603823100000 2 0 6 1603823160000 2 1 7 1603823220000 1 105.0
需要新增PrevValue列,取值为当前行之前最近的Event=1对应的Value值,目标结果如下:
TimeStamp Event Value PrevValue 0 1603822620000 1 102.0 NaN 1 1603822680000 1 108.0 102.0 2 1603822740000 1 107.0 108.0 3 1603822800000 2 1 107.0 4 1603823040000 1 106.0 107.0 5 1603823100000 2 0 106.0 6 1603823160000 2 1 106.0 7 1603823220000 1 105.0 106.0
直接使用shift(1)或groupby('Event').shift(1)无法满足需求,原方法使用apply逐行查询效率极低,需要更高效的实现方式。
高效实现方案
利用Pandas的向量化操作结合向前填充,实现O(n)时间复杂度的高效处理:
import pandas as pd # 构建示例DataFrame data = { 'TimeStamp': [1603822620000, 1603822680000, 1603822740000, 1603822800000, 1603823040000, 1603823100000, 1603823160000, 1603823220000], 'Event': [1, 1, 1, 2, 1, 2, 2, 1], 'Value': [102.0, 108.0, 107.0, 1, 106.0, 0, 1, 105.0] } df = pd.DataFrame(data) # 步骤1:仅保留Event=1的Value,其余行设为NaN df['temp'] = df['Value'].where(df['Event'] == 1) # 步骤2:向前填充NaN,得到每行及之前最近的Event=1的Value df['temp'] = df['temp'].ffill() # 步骤3:整体下移一行,得到当前行之前的最近匹配值,第一行自动变为NaN df['PrevValue'] = df['temp'].shift(1) # 步骤4:清理临时列 df.drop('temp', axis=1, inplace=True) # 输出结果 print(df)
方案优势
- 完全基于Pandas内置的向量化操作,避免了
apply循环的逐行查询(原方法为O(n²)复杂度),数据量越大,性能提升越明显。 - 逻辑清晰,步骤简洁,易于维护和扩展。
内容的提问来源于stack exchange,提问作者mananana
相关产品推荐
相关产品推荐

