我正在努力寻找在Python中执行此操作的最有效方法。我将感谢所有建议。
我有一个数字数据数组;有些元素是NaN。当我找到一个NaN时,我想选择20个最接近的元素,这些元素是有效的数值。所以,在理想情况下,NaN数据点位于中间的某个地方,它之后的10个元素和它之前的10个元素都是有效的数值。在一个更棘手的情况下,NaN前面只有5个元素,我必须选择NaN之后的15个元素。更棘手的情况是NaN之前只有5个元素,而原始NaN之后的15个元素中也有一个NaN,所以我必须选择16个元素(然后过滤掉NaN,得到我需要的15个元素)。
我可以通过从一个嵌套框架中过滤出NaN并保留一个新的原始索引列来做到这一点,但这很混乱,而且我还不是pandas和numpy的Maven。我觉得有一种聪明的方法可以做到这一点。
谢谢你
2条答案
按热度按时间ssm49v7z1#
假设这个例子:
字符串
您可以使用掩码
ffill
、sliding_window_view
和join
的组合:型
输出量:
型
e4yzc0pl2#
我理解,对于每一行,你想向前看10行,并使用它的值,如果它是NA,你想采取下一个非NA值,跟随这一行,同样向前。
假设你有一个列
value
,你想操作它,你可以这样做:字符串
这将向前和向后查看,并假设您在数据集的开头和结尾应用相同的间隙。如果不是这种情况,则可以应用
ffill
和bfill
(见本文结尾)。shift
方法做了主要的技巧。如果你不需要跳过NA值,它就足够了。因为你需要跳过前瞻,你需要向后传播前向的非NA值,以便为每个NA值使用下一个非NA值。而在锁定情况下则恰恰相反。测试数据
例如,我使用
shift_f=shift_b=3
(因此向后和向前锁定仅3步而不是10步)来可视化较小数据集的效果。让我们假设我们对名为value
的列应用该方法感兴趣。我们最初使用与该行索引相等的值填充列中的某些值,以便可以很容易地看到发生了什么。型
结果:
| | 落后|向前| forward |
| --|--|--|--|
| 0 |楠|楠| 3 |
| 1 |楠|楠| 4 |
| 2 | 2 |楠| 5 |
| 3 | 3 |楠| 7 |
| 4 | 4 |楠| 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 |楠|
| 18 |楠| 13 |楠|
| 19 | 19 | 13 |楠|
数据集开始和结束的替代处理
如果你想使用第一个可用值而不是NA,你只需要像这样添加另一个
bfill
/ffill
:型
然后,我们在数据集的开始处有一个较短的lockback,在数据集的结束处有一个较短的lookforward,结果如下所示:
| | 落后|向前| forward |
| --|--|--|--|
| 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 |