如何计算一组后的加权平均价格?

时间:2012-03-28 15:15:43

标签: c# linq datatable

我有以下数据表:

qty     price     date
5         2        1/25
6         1        1/25
8         3        4/25
1         2        4/25

我希望:

qty     price    date
11       1.45     1/25
9        2.88     4/25

我已经按日期将数据表分组

 var groups = ToCalc.AsEnumerable().GroupBy(r => r.Field("trade_date"));

和数量总和如下:

            foreach (var group in groups)
            {
                qty = Convert.ToDouble( group.Sum(r => r.Field("EXEC_QTY")));
            }

但我不知道如何计算加权平均价格。 有什么想法吗?

4 个答案:

答案 0 :(得分:3)

weightedAverage = group.Sum(r => r.Field("EXEC_QTY") * r.Field("price"))
     / group.Sum(r => r.Field("EXEC_QTY"));

如果确实需要,请添加Convert.ToDouble。

由于您评论qty是双精度且价格是小数:

weightedAverage = group.Sum(r => (decimal)r.Field("EXEC_QTY") * r.Field("price"))
     / group.Sum(r => (decimal)r.Field("EXEC_QTY"));

(价格为十进制和数量是否为双倍更有意义吗?或两者都是小数?)

答案 1 :(得分:0)

    class Data
    {
        public int Qty { get; set; }
        public double Price { get; set; }
        public string Date { get; set; }
    }
    static void Main(string[] args)
    {
        var data = new Data[] { 
            new Data { Qty = 5, Price = 2, Date = "1/25"  },
            new Data { Qty = 6, Price = 1, Date = "1/25"  },
            new Data { Qty = 8, Price = 3, Date = "4/25"  },
            new Data { Qty = 1, Price = 2, Date = "4/25"  },
        };

        var weighted = data.GroupBy(x => x.Date)
                           .Select(group => new Data { 
                               Date = group.Key, 
                               Qty = group.Sum(i => i.Qty), 
                               Price = group.Sum(i => i.Price * i.Qty) / group.Sum(i => i.Qty)
                       });            
    }

答案 2 :(得分:0)

我会做这样的事情:

var results = ToCalc.AsEnumerable()
    .GroupBy(r => r.Field("trade_date"))
    .Select(grp => 
            {
                var quantity = grp.Sum(r => r.Field("EXEC_QTY"));
                var avg = grp.Sum(r => r.Field("EXEC_QTY") * r.Field("price")) / quantity;
                return new { 
                               TradeDate = grp.Key, 
                               Quantity = quantity, 
                               WeightedAverage = avg
                           };
            });

results将是一个包含所需信息的匿名对象的可枚举对象,它更易于访问。

答案 3 :(得分:0)

您可以使用this Enumerable.GroupBy重载:

在一个方法中执行所有分组
var groups = ToCalc.AsEnumerable()
    .GroupBy(r => r.date, (k, g) => new
    {
        date = k,
        qty = g.Sum(i => i.qty),
        price = g.Sum(i => i.qty * i.price) / g.Sum(i => i.qty)
    });

这会给你类似的东西:

{ date = "1/25", qty = 11, price = 1.4545454545454546 }
{ date = "4/25", qty = 9, price = 2.8888888888888888 }