C# C LINQ每天对时间序列值排序=>按日期划分,然后按值排序(从大到小)

C# C LINQ每天对时间序列值排序=>按日期划分,然后按值排序(从大到小),c#,linq,ranking,time-series,C#,Linq,Ranking,Time Series,我有一套大约2000个独立的时间序列,以分类列表的形式。每个系列对应于给定证券的每日流动性。我想创建这些价值观的每日排名。如果我使用for循环执行此操作,我将执行以下操作: 为每个安全性创建一个新的空时间序列[date,intrank],以保持其在给定日期的排名。这可以是分类列表的形式。 创建了所有唯一日期的列表,但并非每个证券的时间序列都有每个日期的值。 对于每个唯一的日期,循环遍历每个证券的每日流动性时间序列,以确定其是否具有该日期的值。 如果有,则将证券名称和价值添加到每日排名数组[Sec

我有一套大约2000个独立的时间序列,以分类列表的形式。每个系列对应于给定证券的每日流动性。我想创建这些价值观的每日排名。如果我使用for循环执行此操作,我将执行以下操作:

为每个安全性创建一个新的空时间序列[date,intrank],以保持其在给定日期的排名。这可以是分类列表的形式。 创建了所有唯一日期的列表,但并非每个证券的时间序列都有每个日期的值。 对于每个唯一的日期,循环遍历每个证券的每日流动性时间序列,以确定其是否具有该日期的值。 如果有,则将证券名称和价值添加到每日排名数组[SecName,liquidity value]。 将数组从最大到最小排序,秩1=最大值。 对于数组中的每个security secName,将日期和证券的排名添加到其在步骤1中创建的时间序列中。 简单地说,这是流动性从大到小的每日排名。我可以让linq按日期从对象和组中提取数据,但其余的都超出了我的linq技能

有林克大师愿意试一试吗

对象结构的简化版本概述如下

注:我特意创建了一个日期2011,01,18,其中值30相同。在这种情况下,可以接受按符号名称进行的子排序。所以他们会被排在。。。第一次6753 JT,第二次6754 JT。6752 JT没有该日期的值,因此不包括在内

应该是这样的

6752 JT
  1/15/2011 12:00:00 AM value 30 rank 1
  1/16/2011 12:00:00 AM value 20 rank 2
  1/17/2011 12:00:00 AM value 10 rank 3
6753 JT
  1/15/2011 12:00:00 AM value 20 rank 2
  1/16/2011 12:00:00 AM value 30 rank 1
  1/17/2011 12:00:00 AM value 20 rank 2
  1/18/2011 12:00:00 AM value 30 rank 1
6754 JT
  1/16/2011 12:00:00 AM value 10 rank 3
  1/17/2011 12:00:00 AM value 30 rank 1
  1/18/2011 12:00:00 AM value 30 rank 2

注:最终输出不需要包括用于计算排名的初始值,只需包括日期和排名。我之所以将其包括在内,是因为它使最初的问题更容易理解。

您的数据结构不是非常清晰,但我认为您需要如下内容:

// Initial query just to get a sequence of { Symbol, Date, Value } entries.
var entries = from securityPair in ds.securities
              from valuation in securityPair.Value.timeSeries["liquidity"]
              select new { Symbol = securityPair.Key,
                           Date = valuation.Key,
                           valuation.Value };

// Now do the grouping, sorting and ranking
var groupedByDate = from entry in entries
                    group entry by entry.Date into date
                    select date.OrderByDescending(x => x.Value)
                               .ThenBy(x => x.Symbol)
                               // Use the overload of Select which includes the
                               // index within the sequence (*after* sorting)
                               .Select((x, index) => new {
                                    x.Symbol,
                                    x.Value,
                                    x.Date,
                                    Rank = index + 1,
                                });

// Now group by symbol again
var rankingsBySymbol = groupedByDate.SelectMany(day => day)
                                    .ToLookup(tuple => tuple.Symbol,
                                              tuple => new { tuple.Date,
                                                             tuple.Value,
                                                             tuple.Rank });
这将为您建立一个按符号查找的功能,其中每个符号都有一个按符号值和该日期排名的日期顺序排列的结果列表


至少,这是计划。我根本没有测试过这个…

所需的输出不清楚,我……也许可以添加与之匹配的示例输出?@Marc:我已经编辑了上面的查询,以包含匹配输出的示例。我希望这能让问题更清楚。乔恩,谢谢你的回答。很抱歉,不够清晰。现在我发现我没有创建安全性、日期和值序列。总的来说,我理解你在这里所做的。然而,我并不十分清楚中间查询的select在做什么。我现在就试试。@Andre:中间一位是按日期分组,然后在该日期内对结果排序,这样我们就可以得到排名。我希望这就是你想要的:小点:security.timeSeries应该读security.Value.timeSeries,security.symbol应该读security.Value。symbol@Jon:的确,这正是我想要的@安德烈:您似乎在两个地方有安全符号-作为密钥/值对的密钥和安全本身内的密钥。。。但在示例代码中,您从未在安全性中实际设置它。我的意思是从键/值对的键获取它-将编辑。
6752 JT
  1/15/2011 12:00:00 AM value 30 rank 1
  1/16/2011 12:00:00 AM value 20 rank 2
  1/17/2011 12:00:00 AM value 10 rank 3
6753 JT
  1/15/2011 12:00:00 AM value 20 rank 2
  1/16/2011 12:00:00 AM value 30 rank 1
  1/17/2011 12:00:00 AM value 20 rank 2
  1/18/2011 12:00:00 AM value 30 rank 1
6754 JT
  1/16/2011 12:00:00 AM value 10 rank 3
  1/17/2011 12:00:00 AM value 30 rank 1
  1/18/2011 12:00:00 AM value 30 rank 2
// Initial query just to get a sequence of { Symbol, Date, Value } entries.
var entries = from securityPair in ds.securities
              from valuation in securityPair.Value.timeSeries["liquidity"]
              select new { Symbol = securityPair.Key,
                           Date = valuation.Key,
                           valuation.Value };

// Now do the grouping, sorting and ranking
var groupedByDate = from entry in entries
                    group entry by entry.Date into date
                    select date.OrderByDescending(x => x.Value)
                               .ThenBy(x => x.Symbol)
                               // Use the overload of Select which includes the
                               // index within the sequence (*after* sorting)
                               .Select((x, index) => new {
                                    x.Symbol,
                                    x.Value,
                                    x.Date,
                                    Rank = index + 1,
                                });

// Now group by symbol again
var rankingsBySymbol = groupedByDate.SelectMany(day => day)
                                    .ToLookup(tuple => tuple.Symbol,
                                              tuple => new { tuple.Date,
                                                             tuple.Value,
                                                             tuple.Rank });