基于条件判断与行操作创建Pandas新列的实现咨询
问题描述
我有一个索引非连续的DataFrame,结构如下:
A B a 6.5 1 b 6.8 0 c 7.0 0 f 6.0 1 h 6.1 0 i 6.2 0
需要创建新列C,规则是:
- 当
B=1时,C等于当前行的A值; - 当
B=0时,C等于当前行的A值减去最近一行B=1对应的A值。比如行c的C应该是7.0 - 6.5 = 0.5。
解决方案
嘿,这个需求用pandas的向前填充(ffill())功能就能轻松搞定,我给你一步步拆解实现逻辑:
核心思路是先把所有B=1行的A值标记出来,然后让后面的B=0行“继承”最近的那个标记值,最后用当前行的A减去这个继承值就行(B=1的行直接保留A值)。
直接上可运行的代码:
import pandas as pd import numpy as np # 先构造你给出的DataFrame df = pd.DataFrame( {'A': [6.5, 6.8, 7.0, 6.0, 6.1, 6.2], 'B': [1, 0, 0, 1, 0, 0]}, index=['a', 'b', 'c', 'f', 'h', 'i'] ) # 第一步:生成临时序列,只保留B=1时的A值,其余为NaN last_valid_A = df['A'].where(df['B'] == 1) # 第二步:向前填充NaN,让每个B=0的行拿到最近的B=1的A值 last_valid_A_filled = last_valid_A.ffill() # 第三步:用np.where快速判断生成C列 df['C'] = np.where(df['B'] == 1, df['A'], df['A'] - last_valid_A_filled)
运行之后,你的DataFrame就会变成这样:
A B C a 6.5 1 6.5 b 6.8 0 0.3 c 7.0 0 0.5 f 6.0 1 6.0 h 6.1 0 0.1 i 6.2 0 0.2
补充说明
- 这个方法完全不care索引是不是连续的,因为
ffill()是按数据的行顺序来填充的,和索引无关; - 用
np.where比apply效率更高,尤其是数据量大的时候,推荐用这个写法; - 如果你的DataFrame里第一行就是
B=0,ffill()会保留NaN,这时候你可能需要根据实际情况处理(比如填充默认值),不过你的示例数据里第一行是B=1,所以没问题。
内容的提问来源于stack exchange,提问作者asimo
相关产品推荐
相关产品推荐

