Pandas实现满足状态切换条件时复制列B值到新列C
Pandas实现状态切换时复制列值到新列
需求说明
当列A满足以下状态切换条件时,将对应切换前一行的列B值复制到新建列C中,不满足条件时C列值为0:
- 状态从
Forward切换为Stop或Backward - 状态从
Backward切换为Stop或Forward
示例数据:
| A | B | C |
|---|---|---|
| Stop | 0 | 0 |
| Forward | 10 | 0 |
| Forward | 20 | 0 |
| Forward | 30 | 30 |
| Backward | 10 | 0 |
| Backward | 25 | 0 |
| Backward | 40 | 40 |
| Stop | 0 | 0 |
| Stop | 0 | 0 |
| Backward | 5 | 0 |
| Backward | 10 | 10 |
| Forward | 20 | 0 |
| Forward | 30 | 30 |
| Stop | 0 | 0 |
原代码问题分析
你提供的两段代码均无法生效,核心问题包括:
- 函数定义与apply逻辑脱节:在
iterrows循环内重复定义函数C,但apply调用时无法关联循环内的变量,导致函数无法获取正确的状态对比值。 - 索引逻辑错误:代码1中使用
idx+1会导致索引越界,且状态对比方向搞反;代码2的循环变量未传递给apply的函数,无法实现逐行判断。 - 未处理默认情况:函数
C没有定义不满足条件时的返回值,默认返回None,导致C列全为空。
正确实现方法
推荐使用Pandas的矢量化操作(shift方法)实现,效率远高于iterrows循环:
import pandas as pd # 构造示例数据 data = { 'A': ['Stop', 'Forward', 'Forward', 'Forward', 'Backward', 'Backward', 'Backward', 'Stop', 'Stop', 'Backward', 'Backward', 'Forward', 'Forward', 'Stop'], 'B': [0, 10, 20, 30, 10, 25, 40, 0, 0, 5, 10, 20, 30, 0] } df = pd.DataFrame(data) # 获取上一行的A列值 prev_A = df['A'].shift(1) # 获取上一行的B列值 prev_B = df['B'].shift(1) # 定义状态切换条件 condition = ( ((prev_A == 'Forward') & (df['A'].isin(['Stop', 'Backward']))) | ((prev_A == 'Backward') & (df['A'].isin(['Stop', 'Forward']))) ) # 生成C列:满足条件取上一行B值,否则为0 df['C'] = condition.map(lambda x: prev_B if x else 0).fillna(0).astype(int) print(df)
代码说明
shift(1):将列数据向下偏移一行,得到上一行的状态(prev_A)和对应B值(prev_B)。- 条件判断:通过布尔索引筛选出符合状态切换规则的行。
- 生成C列:对满足条件的行赋值为上一行的B值,其余行赋值为0,最后处理空值并转为整数类型。
执行后输出结果将与示例表格完全一致。
内容的提问来源于stack exchange,提问作者snowballtrader
相关产品推荐
相关产品推荐

