【问题标题】:how one can calculate a weight average price after a group by?如何计算分组后的重量平均价格?
【发布时间】:2012-03-28 15:15:43
【问题描述】:

我有下面的数据表:

数量 价格 日期 5 2 1/25 6 1 1/25 8 3 4/25 1 2 4/25

我想要:

数量 价格 日期 11 1.45 1/25 9 2.88 4/25

我已经用

按日期对数据表进行分组 var groups = ToCalc.AsEnumerable().GroupBy(r => r.Field("trade_date"));

数量总和是这样的:

foreach(组中的 var 组) { 数量 = Convert.ToDouble(group.Sum(r => r.Field("EXEC_QTY"))); }

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

【问题讨论】:

标签: c# linq datatable


【解决方案1】:
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"));

(价格是小数,数量是双倍不是更有意义吗?或者两者都是小数?)

【讨论】:

  • 谢谢,我试过了:price =Convert.ToDouble(group.Sum(r => r.Field("EXEC_QTY") * r.Field("EXEC_PRICE")) /group.Sum(r => r.Field("EXEC_QTY")));但是 EXEC_QTY 是小数,EXEC_Price 是双精度,如何处理?
【解决方案2】:
    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)
                       });            
    }

【讨论】:

    【解决方案3】:

    我会这样做:

    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 将是包含您想要的信息的匿名对象的可枚举,它的结构更易于访问。

    【讨论】:

      【解决方案4】:

      您可以使用this Enumerable.GroupByoverload 在一种方法中执行所有分组:

      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 }
      

      【讨论】:

        猜你喜欢
        • 2020-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-02
        • 1970-01-01
        • 1970-01-01
        • 2021-12-09
        • 2021-12-27
        相关资源
        最近更新 更多