【发布时间】:2019-06-18 20:16:14
【问题描述】:
我想向前填充一列并且我想指定一个限制,但我希望限制基于索引——而不是像限制允许的简单行数。
例如,假设我有以下给出的数据框:
df = pd.DataFrame({
'data': [0.0, 1.0, np.nan, 3.0, np.nan, 5.0, np.nan, np.nan, np.nan, np.nan],
'group': [0, 0, 0, 1, 1, 0, 0, 0, 1, 1]
})
看起来像
In [27]: df
Out[27]:
data group
0 0.0 0
1 1.0 0
2 NaN 0
3 3.0 1
4 NaN 1
5 5.0 0
6 NaN 0
7 NaN 0
8 NaN 1
9 NaN 1
如果我按group 列分组并用limit=2 向前填充该组,那么我的结果数据框将是
In [35]: df.groupby('group').ffill(limit=2)
Out[35]:
group data
0 0 0.0
1 0 1.0
2 0 1.0
3 1 3.0
4 1 3.0
5 0 5.0
6 0 5.0
7 0 5.0
8 1 3.0
9 1 NaN
然而,我在这里真正想做的只是向前填充到索引在每个组的第一个索引的 2 以内的行,而不是每个组的接下来的 2 行。例如,如果我们只查看数据框上的组:
In [36]: for i, group in df.groupby('group'):
...: print(group)
...:
data group
0 0.0 0
1 1.0 0
2 NaN 0
5 5.0 0
6 NaN 0
7 NaN 0
data group
3 3.0 1
4 NaN 1
8 NaN 1
9 NaN 1
我希望这里的第二组仅向前填充到索引 4——而不是 8 和 9。第一组的 NaN 值都在最后一个非 NaN 值的 2 个索引内,因此它们将被完全填充.生成的数据框如下所示:
group data
0 0 0.0
1 0 1.0
2 0 1.0
3 1 3.0
4 1 3.0
5 0 5.0
6 0 5.0
7 0 5.0
8 1 NaN
9 1 NaN
FWIW 在我的实际用例中,我的索引是 DateTimeIndex(并且已排序)。
我目前有一个可行的解决方案,需要遍历在组索引上过滤的数据帧,根据索引为每个具有非 NaN 值的单个事件创建一个时间范围,然后将它们组合起来。但这太慢了,不实用。
【问题讨论】:
-
修改您的示例以使用 DateTimeIndex 并设计出实际满足您希望通过有效答案满足的所有条件的值会很有帮助。
-
@unutbu 确实,很难正确模拟。但我同意这样的例子对未来的读者更有益。我试图更笼统,但这只会增加对有限(如果有的话)好处的混淆。
标签: python pandas dataframe pandas-groupby imputation