2016-12-27 22 views
1

我有以下格式我的數據..獲取數和平均爲具體指標分析,也休息

UserId Property1  Property2  Property3 Testval 
    1   1    1    10   35 
    2   1    2    3   45 
    3   2    5    6   55 
and so on.. 

我有幾個指標分析,一對夫婦的例子是如下..

a) Where Property1=1 and Property3=10 
b) Where Property1!=1 and Property2=5 

我需要的是用戶的數量& testval平均值落在這些標準之內,也是所有其他不符合標準的人。

所以,結果數據結構將是如下..

User Count 

Criteria   Users  
a    100 
b    200 
rest    1000 

TestVal Average 

Criteria   avg  
a    25 
b    45 
rest    15 

我知道如何分別得到具體指標分析的用戶列表。

data.Where(w=>w.Property1==1).Select(s=>s.UserId).ToList() 

但是我如何獲得usercount和avg val,對於其他用戶來說更重要的是相同的。

任何幫助表示衷心感謝

感謝

+1

嘗試'data.Where(W => w.Property1 == 1 && w.Property3 == 10)。平均(R => r.Testval);' –

+0

如果userID是獨特然後,可以將得到標準a和b的結果中不存在的休息。臨時數據表格聽起來很有用。 – Badiparmagi

+0

@M.Wiśnicki好的,但是我怎樣才能得到其餘的條件和其他誰不落在任何條件下的結果數據結構 – Arnab

回答

4

看起來你是通過標準尋求組。例如:

var result = data.GroupBy(x => 
    x.Property1 == 1 && x.Property3 == 10 ? 0 : 
    x.Property1 != 1 && x.Property2 == 5 ? 1 : 
    // ... 
    -1) 
    .Select(g => new 
    { 
     Criteria = g.Key, 
     Users = g.Count(), 
     Avg = g.Average(x => x.Testval), 
    }) 
    .ToList(); 
+0

哦..好吧,然後Criteria = -1給我剩下的價值..是那麼... – Arnab

+1

是的。當然你可以使用任意數字,甚至可以使用「a」,「b」,「rest」等字符串,而不是0,1,...,-1。 –

2

要獲得一個特定的標準計數/平均,很容易

Func<MyUser, boolean> criterion1 = user => user.Property1==1; 
var avg = data.Where(criterion1).Average(user => user.Testval); 
var count = data.Where(criterion1).Count(); 

(這將枚舉數據的兩倍,如果這是一個如此問題,你可以在計算之前實現數據)

如果你想評估多個標準(並且不想重複這個代碼,輸入法是有標準),你可以把它們放在一個字典,而環比他們:

var criteria = new Dictionary<string, Func<MyUser, boolean>>{ 
    { "criterion1", user => user.Property1==1 }, 
    { "criterion2", user => user.Property1!=1 && user.Property2=5 }, 
    //... 
} 

foreach (var criterion in criteria){ 
    var avg = data.Where(criterion.Value).Average(user => user.Testval); 
    var count = data.Where(criterion).Count(); 
    Console.WriteLine($"{criterion.Key} average: {avg}, count: {count}"); 
} 

你也可以把結果在另一個字典中,像

var results = new Dictionary<string, Tuple<string, string>>(); 

foreach (var criterion in criteria){ 
    var avg = data.Where(criterion.Value).Average(user => user.Testval); 
    var count = data.Where(criterion).Count(); 
    results.Add(criterion.Key, Tuple.Create(avg, count)); 
} 

然後進行更好看的報告,或者你甚至可以創建一個更容易打印的特定結果類。爲了得到其餘的數據(不符合任何謂詞的數據的計數/平均值),可以遍歷所有的謂詞,否定它們;

var query = data; 
foreach (var criterion in criteria.Values){ 
    query = query.Where(user => !criterion(user)); 
} 
var restAvg = query.Average(user => user.Testval); 
var count = query.Count(); 
+0

很酷..我該如何處理休息... – Arnab

+0

編輯其餘值的計算。 – SWeko

2

您可以使用select new來返回包含您的條件的新匿名類型對象。

public void Test() 
    { 
     var list = new List<User>(); 
     list.Add(new User {UserId = 1, Property1 = 1, Property2 = 1, Property3 = 10, Testval = 35}); 
     list.Add(new User {UserId = 1, Property1 = 2, Property2 = 2, Property3 = 3, Testval = 45}); 
     list.Add(new User {UserId = 1, Property1 = 5, Property2 = 5, Property3 = 6, Testval = 55}); 

     Func<User, bool> crit = u => u.Property1 == 1 & u.Property3==10; 
     var zz = list.Where(crit) 
      .GroupBy(t => new {ID = t.UserId}) 
      .Select(w => new 
      { 
       average = w.Average(a => a.Testval), 
       count = w.Count(), 
       rest = list.Except(list.Where(crit)).Average(a => a.Testval) 
      }).Single(); 
    }