如何使用 Deedle Frame<DateTime,_> 中的某个键获取行的位置?
How to get the position of the row with some key from a Deedle Frame<DateTime,_>?
我的意思是:
let position:int = positionForKey frame key
let row =
Frame.take positionForKey
|> frame.takeLast 1
那么,row
应该是一个只有一行的Frame,它的key是key
.
我不知道的是如何实现positionForKey
。一个想法应该可行但我不知道这是否是最好的方法是通过 Series.scanValues
创建另一个 Series
并让值成为位置,但我认为应该是一种更优雅的方式。
通过 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 是一个有效的日期时间)
您可以通过多种方式提取键的位置,例如使用 .RowIndex
。但最简单的方法可能就是获取键并找到索引。您可能想使用 TryFindIndex
,其中 df 是数据帧,由 DateTime 索引。
df.RowKeys |> Seq.findIndex(fun x -> x = DateTime(2017,5,6))
如果您只想 return 指定索引处的一行,可以使用扩展方法。以下是按索引获取行的一些方法:
(Frame.getRow (DateTime(2017,5,6)) df):Series<string,string>
或
df.Rows.[(DateTime(2017,5,6))]
如果您想做一些更有趣的事情,您当然应该参考 Deedle, and Frame docs。
Deedle 实际上有 built-in 函数来执行此操作,但它们没有很好的文档记录(主要是因为当我们添加对 "virtual frames" 的支持时这已经发生了很大变化)。
但是,考虑一个示例数据框:
let ts = series [ for i in 0 .. 365 -> DateTime(2017, 1, 1).AddDays(float i) => float i]
let df = frame ["Sample" => ts ]
数据框有一个行索引,表示如何使用索引执行查找。使用RowIndex
,你可以找到key,然后将返回的地址转换为索引:
let addr = df.RowIndex.Locate(DateTime(2017, 5, 1))
let idx = df.RowIndex.AddressOperations.OffsetOf(addr)
然后你可以得到一个只有这一行的框架:
df.GetRowsAt([| int idx |])
当您使用 in-memory 数据帧时,地址 addr
只是索引,但 in virtual data frames 它会是一个编码行存储位置的数字,因此它不会直接映射到偏移量。这就是我添加 OffsetOf
调用的原因,它将地址映射到实际索引。虽然在in-memory帧的情况下,你不需要担心这个。
如果未找到密钥,addr
值将为 -1L
(但原则上,检查时应使用 Addressing.Address.invalid
)。
我的意思是:
let position:int = positionForKey frame key
let row =
Frame.take positionForKey
|> frame.takeLast 1
那么,row
应该是一个只有一行的Frame,它的key是key
.
我不知道的是如何实现positionForKey
。一个想法应该可行但我不知道这是否是最好的方法是通过 Series.scanValues
创建另一个 Series
并让值成为位置,但我认为应该是一种更优雅的方式。
通过 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 是一个有效的日期时间)
您可以通过多种方式提取键的位置,例如使用 .RowIndex
。但最简单的方法可能就是获取键并找到索引。您可能想使用 TryFindIndex
,其中 df 是数据帧,由 DateTime 索引。
df.RowKeys |> Seq.findIndex(fun x -> x = DateTime(2017,5,6))
如果您只想 return 指定索引处的一行,可以使用扩展方法。以下是按索引获取行的一些方法:
(Frame.getRow (DateTime(2017,5,6)) df):Series<string,string>
或
df.Rows.[(DateTime(2017,5,6))]
如果您想做一些更有趣的事情,您当然应该参考 Deedle, and Frame docs。
Deedle 实际上有 built-in 函数来执行此操作,但它们没有很好的文档记录(主要是因为当我们添加对 "virtual frames" 的支持时这已经发生了很大变化)。
但是,考虑一个示例数据框:
let ts = series [ for i in 0 .. 365 -> DateTime(2017, 1, 1).AddDays(float i) => float i]
let df = frame ["Sample" => ts ]
数据框有一个行索引,表示如何使用索引执行查找。使用RowIndex
,你可以找到key,然后将返回的地址转换为索引:
let addr = df.RowIndex.Locate(DateTime(2017, 5, 1))
let idx = df.RowIndex.AddressOperations.OffsetOf(addr)
然后你可以得到一个只有这一行的框架:
df.GetRowsAt([| int idx |])
当您使用 in-memory 数据帧时,地址 addr
只是索引,但 in virtual data frames 它会是一个编码行存储位置的数字,因此它不会直接映射到偏移量。这就是我添加 OffsetOf
调用的原因,它将地址映射到实际索引。虽然在in-memory帧的情况下,你不需要担心这个。
如果未找到密钥,addr
值将为 -1L
(但原则上,检查时应使用 Addressing.Address.invalid
)。