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

基于两列中1的位置对DataFrame执行ffill前向填充的问题

问题:用Pandas实现指定范围前向填充,得到目标结果

原始数据和已写代码

import pandas as pd

prac = pd.DataFrame(
    {"A": [0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], 
     "B": [0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0],
     "DesiredResult": [0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0]}
)

newDf = prac[['A','B']].mask(prac==0)
newDf['buySell'] =  newDf['A'].combine_first(newDf['B'])
newDf['buySell'].ffill(inplace=True)
newDf

已完成的操作

  • 用mask()把A、B列的0转成了NaN;
  • 通过combine_first()把A、B合并成了buySell列;
  • 试了用ffill()前向填充,但出不来DesiredResult的效果,不知道接下来该怎么弄。

解决办法

你现在的问题是单纯ffill()会一直填充到末尾,但目标结果里第6位、第15位要变回0。核心是得控制填充的区间:只有在出现1之后,到下一个A、B全为0的位置之前才填充1,其他地方保持0。

给你两种可行的实现方式:

方式一:分组填充

import pandas as pd

prac = pd.DataFrame(
    {"A": [0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], 
     "B": [0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0],
     "DesiredResult": [0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0]}
)

# 先做一个合并列:A或B是1就记1,否则0
prac['combined'] = (prac['A'] | prac['B']).astype(int)
# 生成分组标识:每次从0变1时,分组号加1
group = (prac['combined'].shift(1) == 0) & (prac['combined'] == 1)
prac['group'] = group.cumsum()
# 按分组前向填充,只有分组号>0的区间填充1,其余保持0
prac['buySell'] = prac.groupby('group')['combined'].ffill()

# 看结果和目标列对比
print(prac[['DesiredResult', 'buySell']])

方式二:标记填充区间

import pandas as pd

prac = pd.DataFrame(
    {"A": [0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], 
     "B": [0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0],
     "DesiredResult": [0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0]}
)

# 标记填充起始点:A或B为1的位置
start_mask = (prac['A'] == 1) | (prac['B'] == 1)
# 标记填充结束点:A、B全为0,且前一个位置是1
end_mask = (prac[['A', 'B']].sum(axis=1) == 0) & (prac[['A', 'B']].shift(1).sum(axis=1) > 0)

# 初始化buySell为0,然后把需要填充的区间设为1
prac['buySell'] = 0
current_fill = False
fill_indices = []

for idx, (start, end) in enumerate(zip(start_mask, end_mask)):
    if start:
        current_fill = True
    if current_fill:
        fill_indices.append(idx)
    if end:
        current_fill = False

prac.loc[fill_indices, 'buySell'] = 1

# 对比结果
print(prac[['DesiredResult', 'buySell']])

两种方法都能得到和DesiredResult完全一致的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 03:43:34