我有一个数据框,我想根据特定条件转发填充。
当条件为 True 时,我想要向前填充和向后填充。条件为 False 意味着该行和下一行之间的链接应该是中断。
当查看我的数据框时,我的意思非常清楚。我的输入如下所示:
condition_values = [True, True, True, False, True, True, False, True,
True, False, True, True, True]
value_values = [0.1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, 0.5, np.nan, 0.9, np.nan]
data = {'condition': condition_values,
'value': value_values}
df = pd.DataFrame(data)
condition value
0 True 0.1
1 True NaN
2 True NaN
3 False NaN
4 True NaN
5 True NaN
6 False NaN
7 True NaN
8 True NaN
9 False 0.5
10 True NaN
11 True 0.9
12 True NaN
我想要的输出如下所示:
condition_values = [True, True, True, False, True, True, False, True, True,
False, True, True, True]
value_values = [0.1,0.1, 0.1, 0.1, np.nan, np.nan, np.nan, 0.5, 0.5, 0.5,
0.9, 0.9, 0.9]
data = {'condition': condition_values,
'value': value_values}
df2 = pd.DataFrame(data)
condition value
0 True 0.1
1 True 0.1
2 True 0.1
3 False 0.1
4 True NaN
5 True NaN
6 False NaN
7 True 0.5
8 True 0.5
9 False 0.5
10 True 0.9
11 True 0.9
12 True 0.9
我尝试制作一堆数据帧,由 Falses、ffill 和 bfill 分割,然后重新连接。必须有一种更快的方法。我非常愿意接受提示而不是完整的解决方案 - 我正在尝试以某种方式解决这个问题。
我一直在努力。 我相信答案实际上在于 groupby。
s = df.condition.shift(1).eq(0).cumsum()
df['value2'] = df.groupby(s).value.ffill().bfill()
这还不完美,但已经实现了。
好的,问题是 ffill().bfill() 会破坏组,因为第二个填充正在处理系列。明白了:
df['value2'] = df.groupby(s).value.ffill()
df['value2'] = df.groupby(s).value.bfill()
你们确实很接近!这是一种方法:
df['value'] = (
df.groupby(
df['condition'].shift().eq(0).cumsum()
.where(df['condition']).ffill()
)['value']
.apply(lambda x: x.ffill().bfill())
.droplevel(0)
)
输出
condition value
0 True 0.1
1 True 0.1
2 True 0.1
3 False 0.1
4 True NaN
5 True NaN
6 False NaN
7 True 0.5
8 True 0.5
9 False 0.5
10 True 0.9
11 True 0.9
12 True 0.9
解释
Series.shift
开始 df['condition']
并检查 Series.eq
为 0(就像您所做的那样)。Series.where
将False
行“重置”到NaN
并应用Series.ffill
,从而将它们添加到上一组。df.groupby
,选择“值”列,然后使用 groupby.apply
将 Series.ffill
和 Series.bfill
应用于每个组。df.droplevel
删除前置索引级别并分配给 df['value']
。