gpt4 book ai didi

python - 具有基于索引的限制的前向填充列

转载 作者:太空宇宙 更新时间:2023-11-03 13:07:21 25 4
gpt4 key购买 nike

我想向前填充一列并且我想指定一个限制,但我希望限制基于索引---而不是像限制允许的简单行数。

例如,假设我有以下数据框:

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 值的事件创建一个时间范围,然后将它们组合起来。但这太慢了,不实用。

最佳答案

import numpy as np
import pandas as pd
df = pd.DataFrame({
'data': [0.0, 1.0, 1, 3.0, np.nan, 22, np.nan, 5, np.nan, np.nan],
'group': [0, 0, 1, 0, 1, 0, 1, 0, 1, 1]})

df = df.reset_index()
df['stop_index'] = df['index'] + 2
df['stop_index'] = df['stop_index'].where(pd.notnull(df['data']))
df['stop_index'] = df.groupby('group')['stop_index'].ffill()
df['mask'] = df['index'] <= df['stop_index']
df.loc[df['mask'], 'data'] = df.groupby('group')['data'].ffill()
print(df)
# index data group stop_index mask
# 0 0 0.0 0 2.0 True
# 1 1 1.0 0 3.0 True
# 2 2 1.0 1 4.0 True
# 3 3 3.0 0 5.0 True
# 4 4 1.0 1 4.0 True
# 5 5 22.0 0 7.0 True
# 6 6 NaN 1 4.0 False
# 7 7 5.0 0 9.0 True
# 8 8 NaN 1 4.0 False
# 9 9 NaN 1 4.0 False

# clean up df
df = df[['data', 'group']]
print(df)

产量

   data  group
0 0.0 0
1 1.0 0
2 1.0 1
3 3.0 0
4 1.0 1
5 22.0 0
6 NaN 1
7 5.0 0
8 NaN 1
9 NaN 1

这会将索引复制到列中,然后创建第二个 stop_index 列,该列是 index 增加的大小(时间)窗口。

df = df.reset_index()
df['stop_index'] = df['index'] + 2

然后它使 stop_index 中的空行匹配 data 中的空行:

df['stop_index'] = df['stop_index'].where(pd.notnull(df['data']))

然后它在每个组的基础上向前填充 stop_index:

df['stop_index'] = df.groupby('group')['stop_index'].ffill()

现在(最后)我们可以定义所需的掩码——我们实际想要前向填充数据的地方:

df['mask'] = df['index'] <= df['stop_index']
df.loc[df['mask'], 'data'] = df.groupby('group')['data'].ffill()

关于python - 具有基于索引的限制的前向填充列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54357758/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com