[英]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.