为 Deedle 中的每个层次索引查找 Stats.max

Finding the Stats.max for each hierarchical index in Deedle

如果我有一个包含 [城市、经销商、已售汽车总数] 的数据集。我如何获得每个城市的顶级经销商以及他们售出的汽车数量?

结果应该是这样的

City1 Dealership A 2000
City2 Dealership X 1000
etc.

我相信这是可能的,但我运气不好,这可能是因为我以错误的方式解决问题。

目前我正在按经销商和城市分组,这会创建一个 Frame<(string*string*int), int>,这让我

City1 Dealership A 1 -> 2000
City1 Dealership B 2 -> 1000
City2 Dealership X 3 -> 1000
City2 Dealership Y 4 -> 500
etc.

但是我很难找到交易最多的经销商。

谢谢。

您可以使用 Series.applyLevel 函数执行此操作。它采用一个序列和一个键选择器,然后将给定的聚合应用于具有给定键的所有行。在您的情况下,密钥选择器只需要从系列的组合密钥中投射经销商。鉴于您的示例数据:

let data = series [
  ("City1", "Dealership A") => 2000
  ("City1", "Dealership B") => 1000
  ("City2", "Dealership X") => 1000
  ("City2", "Dealership Y") => 500 ]

您可以通过以下方式获得结果:

data 
|> Series.applyLevel (fun (c, d) -> d) Stats.max

请注意 Stats.max returns option(对于空系列来说是 None)。您可以使用以下方法获得仅包含数字的系列:

data 
|> Series.applyLevel (fun (c, d) -> d) (Stats.max >> Option.get)

我改编了 Tomas 的答案并将类型输出为 Series<string, (string * int)>

let data = series [
  ("City1", "Dealership A") => 2000
  ("City1", "Dealership B") => 1000
  ("City2", "Dealership X") => 1000
  ("City2", "Dealership Y") => 500 ]

data
|> Series.groupBy (fun k _ -> fst k)
|> Series.mapValues (fun sr ->
  let sorted = sr |> Series.sortBy(fun x -> -x)
  let key = sorted |> Series.firstKey |> snd
  let value = sorted |> Series.firstValue
  key, value )

输出看起来像

City1 -> (Dealership A, 2000) 
City2 -> (Dealership X, 1000) 

已编辑

我假设你有这样的 csv 文件

City,Dealership,TotalCarsSold
City1,Dealership A,2000
City1,Dealership B,1000
City2,Dealership X,1000
City2,Dealership Y,500

这就是我要做的。将其读取为 Frame 并将列作为 Series 并应用上面相同的代码以获得结果。

let df = 
  Frame.ReadCsv("C:/Temp/dealership.csv")
  |> Frame.indexRowsUsing(fun r -> r.GetAs<string>("City"), r.GetAs<string>("Dealership"))
df?TotalCarsSold
|> Series.groupBy (fun k _ -> fst k)
|> Series.mapValues (fun sr ->
  let sorted = sr |> Series.sortBy(fun x -> -x)
  let key = sorted |> Series.firstKey |> snd
  let value = sorted |> Series.firstValue
  key, value )