我有一个 Deedle 数据框,看起来像这样。
val it : Frame<int,string> =
Date size1 size2
13 -> 2013-12-12T00:00:00.103336Z 133 35
14 -> 2013-12-12T00:00:00.105184Z 83 35
15 -> 2013-12-12T00:00:00.107205Z 83 35
16 -> 2013-12-12T00:00:00.109566Z 83 34
17 -> 2013-12-12T00:00:00.115260Z 83 34
18 -> 2013-12-12T00:00:00.133546Z 83 34
20 -> 2013-12-12T00:00:00.138204Z 82 34
22 -> 2013-12-12T00:00:00.140125Z 81 34
我想删除与两者 size1和size2具有相同值的行作为上一行。在伪代码中......
if row?size1 = prevRow?size1 && row?size2 = prevRow?size2 then dropRow
所以在上面的例子中我最终得到:
val it : Frame<int,string> =
Date size1 size2
13 -> 2013-12-12T00:00:00.103336Z 133 35
14 -> 2013-12-12T00:00:00.105184Z 83 35
16 -> 2013-12-12T00:00:00.109566Z 83 34
20 -> 2013-12-12T00:00:00.138204Z 82 34
22 -> 2013-12-12T00:00:00.140125Z 81 34
我相信我想用
Frame.filterRowValues(row - > )
但我不知道如何将一行与前一行进行比较。有一个简单的方法吗?也许我需要转移和加入?
答案 0 :(得分:3)
这可以通过多种方式完成,我不太确定哪种方式最好:
使用shift和join(正如你所说)肯定会工作 - 你需要重命名其中一个框架中的列,以便你可以加入它们,但这对我来说听起来是一个很好的解决方案< / p>
您可以使用frame.Rows |> Series.pairwise
获取包含当前行和上一行的元组,然后使用Series.filter
和Series.map
(从元组中选择第二行)并重新使用 - 使用Frame.ofRows
构建框架。唯一的问题是你总是以这种方式丢失第一行(并且你必须将它添加回来)。
您可以使用Frame.filter
找到上一行。最近发布的版本支持Lookup.Smaller
,可让您轻松完成此操作。
第三个选项的代码如下所示(请注意,帧行需要排序frame.Rows.IsOrdered = true
)才能实现此目的:
frame |> Frame.filterRows (fun k row ->
let prev = frame.Rows |> Series.tryLookup k Lookup.Smaller // New in v1.0
match prev with
| Some prev -> prev?Something <> row?Something
| _ -> true (* always return true for the first row *) )