我正在尝试找到在Python中执行此操作的最有效方法。我将不胜感激所有的建议。
我有一个数字数据数组;有些元素是 NaN。当我找到 NaN 时,我想选择最接近的 20 个有效数值元素。因此,在理想情况下,NaN 数据点位于中间的某个位置,其后面的 10 个元素和前面的 10 个元素都是有效的数值。在更棘手的情况下,NaN 前面只有 5 个元素,而我必须选择 NaN 之后的 15 个元素。更棘手的情况是 NaN 之前只有 5 个元素,而原始 NaN 之后的 15 个元素中也有一个 NaN,所以我必须在之后选择 16 个元素(然后过滤掉 NaN 并得到我需要的 15 个元素)。
我可以通过从数据帧中过滤掉 NaN 并保留新的原始索引列来做到这一点,但它很混乱,而且我还不是 pandas 和 numpy 方面的专家。我感觉有一个聪明的方法可以做到这一点。
谢谢你
我理解,对于每一行,您希望向前查看 10 行并使用其值,如果它是 NA,您希望采用该行后面的下一个非 NA 值,同样向后。
假设您有一个列
value
要对其进行操作,您可以按如下方式操作:
shift = 10
ser_forward = df["value"].ffill().shift(shift)
ser_backward = df["value"].bfill().shift(-shift)
df["forward"] = ser_forward
df["backward"] = ser_backward
这将向前和向后查看,并假设您在数据集的开头和结尾应用相同的间隙。如果不是这种情况,您可以申请
ffill
和 bfill
(请参阅本文末尾)。
测试数据
作为示例,我使用 shift=3(因此仅向前和向后锁定 3 步而不是 10 步)以使用较小的数据集来可视化效果。
import pandas as pd
from random import sample
df = pd.DataFrame(index=list(range(20)))
non_null_indexes = [5, 19, 10, 4, 3, 2, 7, 13, 17]
df.loc[non_null_indexes, "value"] = non_null_indexes
结果: | |价值|前进|向后| |---:|--------:|----------:|-----------:| | 0 |楠 |楠 | 3 | | 1 |楠 |楠 | 4 | | 2 | 2 |楠 | 5 | | 3 | 3 |楠 | 7 | | 4 | 4 |楠 | 7 | | 5 | 5 | 2 | 10 | 10 | 6 |楠 | 3 | 10 | 10 | 7 | 7 | 4 | 10 | 10 | 8 |楠 | 5 | 13 | | 9 |楠 | 5 | 13 | | 10 | 10 10 | 10 7 | 13 | | 11 | 11楠 | 7 | 17 | 17 | 12 | 12楠 | 7 | 17 | 17 | 13 | 13 | 10 | 10 17 | 17 | 14 | 14楠 | 10 | 10 17 | 17 | 15 | 15楠 | 10 | 10 19 | 19 | 16 | 16楠 | 13 | 19 | 19 | 17 | 17 17 | 17 13 |楠 | | 18 | 18楠 | 13 |楠 | | 19 | 19 19 | 19 13 |南|
数据集开头和结尾的替代处理
如果对于第一个值,您想使用第一个可用值而不是 NA,则只需添加另一个
bfill
/ ffill
,如下所示:
shift = 3
ser_forward = df["value"].ffill().shift(shift).bfill()
ser_backward = df["value"].bfill().shift(-shift).ffill()
df["forward"] = ser_forward
df["backward"] = ser_backward
结果如下:
价值 | 前进 | 向后 | |
---|---|---|---|
0 | 南 | 2 | 3 |
1 | 南 | 2 | 4 |
2 | 2 | 2 | 5 |
3 | 3 | 2 | 7 |
4 | 4 | 2 | 7 |
5 | 5 | 2 | 10 |
6 | 南 | 3 | 10 |
7 | 7 | 4 | 10 |
8 | 南 | 5 | 13 |
9 | 南 | 5 | 13 |
10 | 10 | 7 | 13 |
11 | 南 | 7 | 17 |
12 | 南 | 7 | 17 |
13 | 13 | 10 | 17 |
14 | 南 | 10 | 17 |
15 | 南 | 10 | 19 |
16 | 南 | 13 | 19 |
17 | 17 | 13 | 19 |
18 | 南 | 13 | 19 |
19 | 19 | 13 | 19 |