繁体   English   中英

根据另一行向前或向后填充

[英]Fill forwards or backwards depending on another row

我有一个如下数据框:

 loc status   ID
0   LA    NaN  NaN
1  CHC    NaN  NaN
2  NYC    ARR   32
3  CHC    DEP   45
4  SEA    NaN  NaN

我试图根据状态列填充ID列中的缺失值。 如果状态列为“ ARR”:我想向后填充,并且如果状态列为“ DEP”:我想向前填充,这样我的最终数据帧将如下所示:

  loc status  ID
0   LA    NaN  32
1  CHC    NaN  32
2  NYC    ARR  32
3  CHC    DEP  45
4  SEA    NaN  45

我一直在尝试通过使用2 for循环遍历两列来实现这一点,但是我想知道在Pandas中是否有一种更有效的方法?

这应该工作

dt.ID.fillna(method='bfill').fillna(method='ffill')

它将使用先前的非NA值填充NA值(先反向,然后转发)

编辑:

也许这就是您要寻找的(基于评论)

dt.ID.fillna(method='ffill').where(dt.ID.notnull() | (dt.status.shift(1) == 'DEP'), dt.ID.fillna(method='bfill').where(dt.ID.notnull() | (dt.status.shift(-1) == 'ARR')))

它不是很可读,但是应该给出一个总体思路

您可以通过根据要向前填充还是向后填充这些行来划分数据帧df来实现此目的:

创建您的df的两个副本,一个副本将所有内容都填满,另一个将所有内容都填满

fill_forward = df.status.fillna(method='ffill') 
fill_backward = df.status.fillna(method='bfill') 

获取前向填充导致行被'DEP'填充的行的索引,以及向后填充导致行被'ARR'填充的行的索引(即,您的两个条件)

forward_index = df.index[(df.status != fill_forward) & (fill_forward == 'DEP')]
backward_index = df.index[(df.status != fill_backward) & (fill_backward == 'ARR')]

更新这些索引,使它们包括紧接在前的行(在向前填充时使用)或紧随在后的行(在向后填充时使用)。

forward_rows = sorted(list({ind for f in forward_index for ind in [f,f-1]}))
backward_rows = sorted(list({ind for b in backward_index for ind in [b,b+1]}))

为每个索引列表填充(使用适当的方法),并将更新的值分配给原始df。 请注意,通过先进行正向填充,您可以优先选择索引重叠时的正向填充。

df.ID.iloc[forward_rows] = df.ID.iloc[forward_rows].fillna(method='ffill')
df.ID.iloc[backward_rows] = df.ID.iloc[backward_rows].fillna(method='bfill')

print(df)

   loc status    ID
0   LA    NaN  32.0
1  CHC    NaN  32.0
2  NYC    ARR  32.0
3  CHC    DEP  45.0
4  SEA    NaN  45.0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM