You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pandas识别DataFrame每行的最后变更类型

需求描述

现有如下Pandas DataFrame:

import pandas as pd

data = [[1, 1, 'no'], [2, 1, 'no'], [3, 3, 'pos'], [4, 3, 'no'], [5, 3, 'no'], 
        [6, 2, 'neg'], [7, 2, 'no'], [8, 2, 'no'], [9, 3, 'pos'], [10, 3, 'no']]
df = pd.DataFrame(data=data, columns=['seq', 'val', 'change'])

原始数据结构:

seq  val change
0    1    1     no
1    2    1     no
2    3    3    pos
3    4    3     no
4    5    3     no
5    6    2    neg
6    7    2     no
7    8    2     no
8    9    3    pos
9   10    3     no

其中change列标记val的变更状态:值增加为pos,减少为neg,无变更为no。需要新增一列last change,记录每行对应的最近一次变更类型,直到下一次变更出现,期望输出如下:

data = [[1, 1, 'no', 'no'], [2, 1, 'no', 'no'], [3, 3, 'pos', 'pos'], [4, 3, 'no', 'pos'], [5, 3, 'no', 'pos'], 
        [6, 2, 'neg', 'neg'], [7, 2, 'no', 'neg'], [8, 2, 'no', 'neg'], [9, 3, 'pos', 'pos'], [10, 3, 'no', 'pos']]
df_desired = pd.DataFrame(data=data, columns=['seq', 'val', 'change', 'last change'])

期望的数据结构:

seq  val change last change
0    1    1     no          no
1    2    1     no          no
2    3    3    pos         pos
3    4    3     no         pos
4    5    3     no         pos
5    6    2    neg         neg
6    7    2     no         neg
7    8    2     no         neg
8    9    3    pos         pos
9   10    3     no         pos

实现方法

通过前向填充非空变更标记的思路即可实现,具体步骤:

  1. 将change列中无变更的no替换为缺失值,只保留有效变更标记;
  2. 用ffill()方法将最近的有效变更标记向下填充到后续行;
  3. 把开头未出现变更的缺失值填充为no,得到目标列。

完整代码:

import pandas as pd

data = [[1, 1, 'no'], [2, 1, 'no'], [3, 3, 'pos'], [4, 3, 'no'], [5, 3, 'no'], 
        [6, 2, 'neg'], [7, 2, 'no'], [8, 2, 'no'], [9, 3, 'pos'], [10, 3, 'no']]
df = pd.DataFrame(data=data, columns=['seq', 'val', 'change'])

# 生成last change列
df['last change'] = df['change'].replace('no', pd.NA).ffill().fillna('no')

print(df)

运行后输出结果与期望完全一致。


内容的提问来源于stack exchange,提问作者Quinten

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 00:35:18