如何按第一列值对动态定义的列表进行分组并计算其余列的平均值?

How to group a dynamically defined list by the first columns value and calculate average for the rest?

我有一个动态定义的嵌套字符串列表,将使用 .txt 填充;

txt的典型值如下:

EPC1687626298729872,12.4,11.3,6.2 EPC1687626298729872,5,6,2
EPC1687626298729872,8,7.3,4 EPC1687626DDDD29872,11.4,10.3,5.2
EPC1687626DDDD29872,9,16,2 EPC2798272987298798,17,2,2
EPC2987398239879832,11,3,2 EPC9827298729872987,4,5,6
EPC3929873981310091,2,2,2 EPC982733U209309280,4,7,11

始终需要第一列的值(从 EPC 开始)。 我需要做的是将具有相同 EPC(第一列值)的行分组,然后按出现次数对其余值进行平均。

例如

EPC1687626298729872,12.4,11.3,6.2 EPC1687626298729872,5,6,2
EPC1687626298729872,8,7.3,4 EPC1687626DDDD29872,11.4,10.3,5.2
EPC1687626DDDD29872,9,16,2

应该给

EPC1687626298729872, (12.4+5+8)/3, (11.3+6+7.3)/3, (6.3+2+4)/3.
EPC1687626DDDD29872, (11.4+9)/2 ,(10.3+16)/2, (5.2+2)/2

提前感谢您的帮助。

您可以利用 LINQ 来完成此任务,因为它提供了许多用于分组、计算平均值和所有其他类型的数据操作的方法。

解析您的数据

由于您有一系列同时包含字符串和数字数据的字符串,因此您需要拆分每个元素,然后拆分这些单独的元素,即:

  • 使用空格和换行符拆分现有输入以提供每个元素(例如 EPC1687626298729872,12.4,11.3,6.2)。
  • 然后使用逗号作为分隔符将这些元素中的每一个分开,为您提供各自的值(例如 { Name : EPC1687626298729872, P1 : 12.4, ... })。

这可以通过 String.Split() method along with LINQ's Enumerable.Select() 方法轻松完成,可能如下所示:

// Separate each of your elements
var elements = input.Split(new string[]{" ", Environment.NewLine},StringSplitOptions.RemoveEmptyEntries)
                    // Separate each element of the string
                    .Select(x => x.Split(','))
                    // Now you have a series of arrays for each element, so map each 
                    // into an object
                    .Select(x => new {
                            Name = x[0],
                            P1 = Decimal.Parse(x[1]),
                            P2 = Decimal.Parse(x[2]),
                            P3 = Decimal.Parse(x[3])
                    });

对您的数据进行分组

解析完所有元素后,现在您可以将它们分组到对象中,以便计算总平均值:

这可能看起来像:

// At this point you have all of your elements, so now group them 
// by their names and average
var groups = elements.GroupBy(x => x.Name)
                     .Select(x => new { 
                            Name = x.Key, 
                            P1 = x.Average(y => y.P1),
                            P2 = x.Average(y => y.P2),
                            P3 = x.Average(y => y.P3)
                     });

此时,您只需遍历结果并获得所需内容即可: