为什么 Deedle 将 DataFrame 布尔列转换为 float 系列?

Why is Deedle casting a DataFrame boolean column into a float Series?

当我 运行 下面的代码时,我得到一个 DataFrame,其中有一个 bool 列和两个 double 列。但是,当我将 bool 列提取为 Series 时,结果是一个类型为 DateTimefloat 的 Series 对象。

看起来 Deedle "cast" 列为另一种类型。

为什么会这样?

open Deedle
let dates  = 
      [ DateTime(2013,1,1); 
        DateTime(2013,1,4); 
        DateTime(2013,1,8) ]

let values = [ 10.0; 20.0; 30.0 ]
let values2 = [ 0.0; -1.0; 1.0 ]


let first = Series(dates, values)
let second = Series(dates, values2)
let third: Series<DateTime,bool> = Series.map (fun k v -> v > 0.0) second

let df1 = Frame(["first"; "second"; "third"], [first; second; third])

let sb = df1.["third"]

df1;;
val it : Frame<DateTime,string> =
  Deedle.Frame`2[System.DateTime,System.String]
    {ColumnCount = 3;
     ColumnIndex = Deedle.Indices.Linear.LinearIndex`1[System.String];
     ColumnKeys = seq ["first"; "second"; "third"];
     ColumnTypes = seq [System.Double; System.Double; System.Boolean];
     ...

sb;;
val it : Series<DateTime,float> = ...

您可以使用 .GetColumn 将系列提取为布尔值:

let sb':(Series<DateTime,bool>) = df1.GetColumn("third")
//val sb' : Series<DateTime,bool> =
//series [ 2013/01/01 0:00:00 => False; 2013/01/04 0:00:00 => False; 2013/01/08 0:00:00 => True]

至于你问的为什么,我没有查看源代码,但我假设你使用的索引器类型可能是 returns 和 obj,然后 Deedle 会尝试将其转换为某些东西,或者它可能会尝试将所有内容都转换为 float

正如现有答案所指出的那样,GetColumn 是必经之路。调用GetColumn时可以直接指定泛型参数,避免类型注解,代码更漂亮:

let sb = df1.GetColumn<bool>("third")

Deedle frame 不会静态地跟踪列的类型,因此当您想要将列作为类型​​化系列获取时,您需要以某种方式指定类型。

我们不想强迫人们编写类型注释,因为它们往往又长又丑,所以获取列的主要方法是 GetColumn,您可以在其中指定类型参数,如上面的例子。

访问列的其他方法,如 df?thirddf.["third"] 是假定列类型为 float 的简写,因为这恰好是很常见的情况(至少对于Deedle 在金融领域最常见的用途),因此这两个符号为您提供了一种比 "often works nicely".

更简单的方法