如何按第一列值对动态定义的列表进行分组并计算其余列的平均值?
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])
});
对您的数据进行分组
解析完所有元素后,现在您可以将它们分组到对象中,以便计算总平均值:
- 通过
Enumerable.GroupBy()
方法按 "Name" 或 "Id" 对每个元素进行分组。
- 使用组通过 LINQ 的
Enumerable.Average()
方法计算平均值。
这可能看起来像:
// 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)
});
此时,您只需遍历结果并获得所需内容即可:
我有一个动态定义的嵌套字符串列表,将使用 .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])
});
对您的数据进行分组
解析完所有元素后,现在您可以将它们分组到对象中,以便计算总平均值:
- 通过
Enumerable.GroupBy()
方法按 "Name" 或 "Id" 对每个元素进行分组。 - 使用组通过 LINQ 的
Enumerable.Average()
方法计算平均值。
这可能看起来像:
// 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)
});
此时,您只需遍历结果并获得所需内容即可: