我的意思是:
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 = 2
,positionforKey f 05/01/01 = 3
等等。 (假设04/01/01是有效的DateTime)
答案 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))]
如果你想做更好的事情,你当然应该咨询Deedle和Frame docs。