如何使用Deedle Frame <datetime,_>中的某个键来获取行的位置?

时间:2017-01-26 21:21:55

标签: f# deedle

我的意思是:

let position:int = positionForKey frame key
let row =
  Frame.take positionForKey
  |> frame.takeLast 1

然后,row应该是一个只有一行的框架,其关键字为key

我不知道如何实现positionForKey。应该有效的一个想法,但我不知道这是否是最好的方法是通过Series创建另一个Series.scanValues并让值为位置,但我认为有些这是一种更优雅的方式。

Series.scanValues的实施将是:

let positionForKey (frame:Frame<'K,_>) (key:'K) =
  let positions = Series.scanValues (fun pos _ -> pos + 1) 0 (frame.GetColumnAt 0)
  positions.[key]

...从1开始的索引

示例

假设你有一个f这样的框架:

03/01/01,  4 , ...
04/01/01,  3 , ...
05/01/01,  6 , ...
   ...  , ..., ...

然后,positionforKey f 04/01/01 = 2positionforKey f 05/01/01 = 3等等。 (假设04/01/01是有效的DateTime)

2 个答案:

答案 0 :(得分:3)

Deedle实际上有这样做的内置函数,但它们没有很好的文档记录(主要是因为当我们添加对#34;虚拟帧&#34;的支持时,这已经发生了很大的变化。)。 p>

但是,请考虑一个示例数据框:

let ts = series [ for i in 0 .. 365 -> DateTime(2017, 1, 1).AddDays(float i) => float i]
let df = frame ["Sample" => ts ]

数据框有一个行索引,表示如何使用索引执行查找。使用RowIndex,您可以找到密钥,然后将返回的地址转换为索引:

let addr = df.RowIndex.Locate(DateTime(2017, 5, 1))
let idx = df.RowIndex.AddressOperations.OffsetOf(addr)

然后你可以得到一个只有这一行的框架:

df.GetRowsAt([| int idx |])

地址addr只是处理内存数据帧时的索引,但是in virtual data frames它将是一个编码行存储位置的数字,因此它不会直接映射抵消。这就是我添加OffsetOf调用的原因,该调用将地址映射到实际索引。虽然在内存帧中,您无需担心这一点。

如果找不到密钥,addr值将为-1L(但原则上,您在检查时应使用Addressing.Address.invalid。)

答案 1 :(得分:1)

您可以通过多种方式提取密钥的位置,例如使用.RowIndex。但最简单的方法可能就是获取密钥并找到索引。您可能希望使用TryFindIndex,其中df是数据帧,由DateTime索引。

df.RowKeys |> Seq.findIndex(fun x -> x = DateTime(2017,5,6))

如果您只想在指定的索引处返回一行,则有一种扩展方法。以下是通过索引获取行的一些方法:

(Frame.getRow (DateTime(2017,5,6)) df):Series<string,string>

df.Rows.[(DateTime(2017,5,6))]

如果你想做更好的事情,你当然应该咨询DeedleFrame docs