用两个键计算加权平均值的功能是难以捉摸的

时间:2013-11-19 03:33:44

标签: c# performance linq linq-to-objects

我在SQL数据库中有一个表,其中包含以下字段:[Cid, Qid, Uid, score, Date]。 但是,Cid并不重要,但它是主键。

我需要得到score Gidped By Qid和Uid的加权平均值。权重定义为(score)*(1.25^n)n是距离第一行具有相同Qid和Uid的行数。 [即Qid和Uid的第一行的n为0.第二行(具有较晚日期但仍为相同Qid和Uid的行)的n为1。]

所以,

Qid    Uid   Date     BS
1       1    9/12/13  .5
1       2    9/13/13  .8
1       2    9/14/13  .5
1       2    9/15/13  .9
2       1    9/12/13  .75
2       1    9/13/13  .8
2       2    9/12/13  .75

该函数应该返回:

Qid  Uid  WeightedAvg  (the weights are applied and then the average is taken)
1     1    .5
1     2    .94375
2     1    .5833
2     2    .75

1 个答案:

答案 0 :(得分:1)

试试这个: -

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LinqToObjects
{
    class Custom
    {
        public int Qid { get; set; }
        public int Uid { get; set; }
        public DateTime Date { get; set; }
        public double BS { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            List<Custom> lst = new List<Custom>()
            {
                new Custom(){ Qid=1, Uid=1, Date=new DateTime(2013,9,12) ,BS=0.5},
                new Custom(){ Qid=1, Uid=2, Date=new DateTime(2013,9,13) ,BS=0.8},
                new Custom(){ Qid=1, Uid=2, Date=new DateTime(2013,9,14) ,BS=0.5},
                new Custom(){ Qid=1, Uid=2, Date=new DateTime(2013,9,15) ,BS=0.9},
                new Custom(){ Qid=2, Uid=1, Date=new DateTime(2013,9,12) ,BS=0.75},
                new Custom(){ Qid=2, Uid=1, Date=new DateTime(2013,9,13) ,BS=0.8},
                new Custom(){ Qid=2, Uid=2, Date=new DateTime(2013,9,12) ,BS=0.75}
            };

            var query = lst.GroupBy(obj => new { obj.Qid, obj.Uid}, ( key,group) => new {Key1= key.Qid, Key2 = key.Uid, Avg = group.Average(o=>o.BS), lst = group});

            Console.WriteLine("Qid\tUid\tWeightedAvg");
            foreach(var item in query)
            {
                double weightAvg=0;
                int cnt = 0;
                foreach (var i in item.lst)
                {
                    weightAvg += i.BS * (Math.Pow(1.25, cnt++));
                }

                weightAvg /= item.lst.Count();

                Console.WriteLine(string.Format("{0}\t{1}\t{2}", item.Key1, item.Key2, weightAvg)) ;
            }

        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LinqToObjects
{
    class DateComparer : IEqualityComparer<Custom>
    {

        public bool Equals(Custom x, Custom y)
        {
            if (Object.ReferenceEquals(x.Date, y.Date)) return true;

            return false;
        }

        public int GetHashCode(Custom obj)
        {
            if (Object.ReferenceEquals(obj, null)) return 0;

            int hashCode = obj.GetHashCode();

            return  hashCode;
        }
    }
}

<强>输出: -

Qid     Uid     WeightedAvg
1       1       0.5
1       2       0.94375
2       1       0.875
2       2       0.75
Press any key to continue . . .