使用linq分组经验总结
来源:互联网 发布:淘宝开店起步 编辑:程序博客网 时间:2024/06/11 20:41
public class NumericStockData { /// <summary> /// 取值 /// </summary> public double? Value { get; set; } public NumericStockData() { } public NumericStockData(DateTime time,string stockCode,double? value) { Time = time; StockCode = stockCode; Value = value; } } public partial class NumericStockDataList:List<NumericStockData> { public NumericStockDataList() : base() { } public NumericStockDataList(IEnumerable<NumericStockData> linq) : base(linq) { } public NumericStockDataList(int capacity) : base(capacity) { } }
操作一:对一个集合StockList按照时间分组后,组内求均值,将此均值覆盖组内的每一项。返回每一项。
示例图:
第一步,按照时间点分组
日期
股票代码
收盘价
2014/01/25
000001
14.5
2014/01/25
000002
21.7
2014/01/26
000001
14.9
2014/01/26
000002
22.5
2014/01/27
000001
15.3
2014/01/27
000002
21.4
第二步:分组计算
日期
股票代码
收盘价
2014/01/25
000001
18.1
2014/01/25
000002
18.1
2014/01/26
000001
18.7
2014/01/26
000002
18.7
2014/01/27
000001
18.35
2014/01/27
000002
18.35
实现方法:public static NumericStockDataList Gave1(NumericStockDataList StockList) { IEnumerable<NumericStockData> linq = from stock in StockList group stock by stock.Time into g//按时间分组 let avg = g.Average(y => y.Value)//组均值 from gstock in g select new NumericStockData() { Time = gstock.Time, StockCode = gstock.StockCode, Value = avg }; return new NumericStockDataList(linq); }
操作二:
1. 按照日期进行分组
2. 分组按照排序要求 DESC对指标值进行排序
3. 分组填写排序结果,增加一列排名列。分组根据顺序填写排名顺序。
示例图:
RANK(现价, DESC)
① 数据
股票代码
现价
6501
100
6502
200
6503
300
6504
400
6505
500
6506
700
6507
650
6508
300
② 降序排序
股票代码
现价
6506
700
6507
650
6505
500
6504
400
6503
300
6508
300
6502
200
6501
100
③ 进行排名
股票代码
现价
排名
6506
700
1
6507
650
2
6505
500
3
6504
400
4
6503
300
5
6508
300
5
6502
200
7
6501
100
8
④ 结果
股票代码
现价
结果
6501
100
8
6502
200
7
6503
300
5
6504
400
4
6505
500
3
6506
700
1
6507
650
2
6508
300
5
实现方法:
操作三:public static NumericStockDataList Rank(NumericStockDataList StockList) { linq = from stock in StockList group stock by stock.Time into g//按时间分组 from gInside in g orderby gInside.Value ascending, gInside.Value.HasValue descending let gList = g.OrderByDescending(y => y.Value).ToList()//组内按值降序 select new NumericStockData() { Time = gInside.Time, StockCode = gInside.StockCode, Value = (double?)gList.FindIndex(x => x.Value == gInside.Value) + 1,//按所在位置排名,若有重复取第一次出现的位置 }; return new NumericStockDataList(linq); }
1. 对成分股按照日期进行分组
2. 系统对股票指标值进行降序排序,
3. 新增一列,根据排序顺序填写排名
4. 对排名结果进行调整,具体规则为:指标值相同的,排名结果为相同指标值的排序做数值平均运算
5. 计算出各组排名的上下限数值
6. 将成分股排名数值与分组的排名数值上下限进行比较,对股票进行分组
示例图:
QUANTILE(现价,NUMSTOCKS,5)
<根据股票个数分组>
1.数据 2.用现价降序排序,再排名
股票代码
现价
现价
排名1
排名调整
6501
100
5000
1
1
6502
200
4500
2
2
6503
300
4200
3
3
6504
400
4000
4
4
6505
500
2000
5
5
6506
700
1000
6
6
6507
650
700
7
7.5
6508
300
700
8
7.5
6509
300
650
9
9.5
6510
400
650
10
9.5
6511
500
600
11
11.5
6512
700
600
12
11.5
6513
650
500
13
14
6514
300
500
14
14
6515
1000
500
15
14
6516
2000
400
16
17
6517
300
400
17
17
6518
4200
400
18
17
6519
4500
300
19
22
6520
600
300
20
22
6521
400
300
21
22
6522
5000
300
22
22
6523
4000
300
23
22
6524
600
300
24
22
6525
500
300
25
22
6526
300
200
26
26
6527
300
100
27
27
3.分组
每个组合的股票个数=股票数/分组数
每个组合的股票个数=27/5=5.4
下边线
上边线
排名
第1组
0
5.4
1
第2组
5.4
10.8
2
第3组
10.8
16.2
3
第4组
16.2
21.6
4
第5组
21.6
27
5
4.分位化
股票代码
现价
排名调整
结果
6522
5000
1
1
6519
4500
2
1
6518
4200
3
1
6523
4000
4
1
6516
2000
5
1
6515
1000
6
2
6506
700
7.5
2
6512
700
7.5
2
6507
650
9.5
2
6513
650
9.5
2
6520
600
11.5
3
6524
600
11.5
3
6505
500
14
3
6511
500
14
3
6525
500
14
3
6504
400
17
4
6510
400
17
4
6521
400
17
4
6503
300
22
5
6508
300
22
5
6509
300
22
5
6514
300
22
5
6517
300
22
5
6526
300
22
5
6527
300
22
5
6502
200
26
5
6501
100
27
5
实现方法:
public static NumericStockDataList Quantile(NumericStockDataList StockList, string type, double nValue) { IEnumerable<NumericStockData> linq = from rankedList in ( from stock in StockList.AddNullToBeMatrix() group stock by stock.Time into g//按时间分组 let gList = g.OrderByDescending(x => x.Value).ToList()//现价降序 let HasNull = g.Where(x => !x.Value.HasValue).Count() > 0 from stockGroup in g let firstIndex = HasNull ? null : (double?)gList.FindIndex(x => x.Value == stockGroup.Value) + 1//相同值第一次出现的下标 let lastIndex = HasNull ? null : (double?)gList.FindLastIndex((int)firstIndex - 1, x => x.Value == stockGroup.Value) + 1//相同值最后一次出现的下标 let seperate = (double)g.Count() / n //排名:组内自然排序后,相同的值取排序值均值 select new { Time = stockGroup.Time, StockCode = stockGroup.StockCode, Value = firstIndex == null ? null : (double?)(firstIndex + lastIndex) / 2,//排名:当Value出现空值时,排名为空 Seperate = seperate, IndustryIds = stockGroup.IndustryIds } ) orderby rankedList.Value//按排名升序 select new NumericStockData() { Time = rankedList.Time, StockCode = rankedList.StockCode, Value = rankedList.Value.HasValue ? System.Math.Ceiling((double)rankedList.Value / rankedList.Seperate) : rankedList.Value,//组号=排名/组数,向上取整;当排名为空时,组号为空 IndustryIds = rankedList.IndustryIds }; return new NumericStockDataList(linq);}
总结:
1。这样理解分组的linq:分组后,每一组都是IEnumerable类型,可以对组内的项迭代。
迭代的方法即from x in xx。即可看作foreach(var x in xx)
2.巧用判断条件:
let:声明局部变量,其作用范围是嵌套在每个from x in xx之间。可以在此处设置判断条件
即:from x in xx
let v=1;
group x by x.Time into g
from gInside in g
let y=2
select {};
等价于 将xx分组后
var v=1;
foreach(var g in xx.GroupBy(i=>i.Tme))
{
foreach(var gInside in g)
{
var y=2;
}
3。注意:对于大数据量(100000数量级以上),使用linq分组、筛选、排序的组合组度很慢。远不如for速度快,虽然写法极其优美。
- 使用linq分组经验总结
- Linq使用Group By经验总结
- 使用linq 中的GroupBy分组
- 使用Linq进行数据分组
- LINQ 分组
- 使用LINQ to Entities查询:分组数据
- c# Linq Lamda表达式使用 GroupBy 分组
- linq to sql 连接分组 使用join和into
- DataTable 使用linq方法获得某列分组列表
- C#之LINQ基础 使用group将数据分组
- linq 分组统计
- linq分组拼接字符串
- linq分组统计
- datatable 分组 linq
- LINQ 分组 总结
- Linq成绩分组
- LINQ分组查询统计
- C#Linq分组汇总
- 【Ecstore2.0】计划任务/队列/导入导出 的执行问题
- spring的一些常用注解
- JPEG文件数据结构以及将位图保存为JPG的代码
- 创建weblogic启动文件,防止出现关闭控制台服务被关掉
- ubuntu14.04中安装opencv2.4.10
- 使用linq分组经验总结
- 西门子S7 200系列寄存器地址与组态王地址的换算公式
- C#事件(event)解析
- node项目的文件说明
- IOS的AutoresizingMask和AutoLayout
- 键盘灯亮但无法输入
- C - ACboy needs your help again!
- 2014-2015年度总结
- android开发混淆文件proguard.cfg详解