按F#中的数值范围分组

时间:2017-04-11 15:28:02

标签: f# deedle

如何按F#和/或Deedle中的数字范围进行分组。即我正在寻找脚下的数据,我想分组成500英尺的桶。

E.g。

我有像

这样的数据

5000 5200 5700 5800 6100 6200 6300

我想要小组

{5000,5200} {5700,5800} {6100,6200,6300}

2 个答案:

答案 0 :(得分:5)

正如你在问题中提到的Deedle,我将根据Deedle系列添加答案。如果您有一些观察结果并希望根据密钥(例如观察时间)对数据进行分组,这将非常有用。说我们有:

let obs = series [ 5000 => 1.0; 5200 => 2.0; 5700 => 3.0; 5800 => 4.0; 
                   6100 => 5.0; 6200 => 6.0; 6300 => 7.0 ]

现在,您可以使用以下命令为每个存储桶创建包含一系列值的系列:

obs |> Series.chunkWhile (fun k1 k2 -> k1/500 = k2/500)

这与Fyodor的回答相同 - 我们会将事物保存在一个桶中,只要除以500的键对于桶中的所有项目都是相同的。

如果您想进行一些进一步的计算,例如获取系列中每个起点的平均每桶,这将非常有用:

obs 
|> Series.chunkWhile (fun k1 k2 -> k1/500=k2/500)
|> Series.mapKeys (fun k -> (k / 500) * 500)
|> Series.mapValues Stats.mean

但是,如果您只想在问题中计算群体,那么Deedle可能有点过分。

答案 1 :(得分:4)

并不完全清楚你的意思是" 500英尺的水桶"。如果我假设一个"桶"被定义为范围500*N .. 500*(N+1),其中N是整数,那么您可以通过整数除以500来轻松获得给定数字所属的存储桶的索引。然后您可以按此分组指数:

let data = [5000; 5200; 5700; 5800; 6100; 6200; 6300]
let groups = data |> Seq.groupBy (fun x -> x/500)

> 
val groups : seq<int * seq<int>> =
  seq
    [(10, seq [5000; 5200]); (11, seq [5700; 5800]);
     (12, seq [6100; 6200; 6300])]