2017-06-13 86 views
0

假設我有一個DataTable名爲a像下面這樣:只有通過一個數據集的四分位分析

|DateTimeSec|value| 
|-----------|-----| 
|14569980000|8 | 
|14570050000|54 | 
|14570900000|928 | 
|14571250000|67 | 
|14571260000|124 | 
|14572230000|32 | 
|14573980000|211 | 
|14574120000|202 | 
|-----------|-----| 

我想要做的就是以某種方式只能改變,例如增加10只中的值基於上述value列的四分位間距。這將導致只有54,67,124和202被改變。我想這樣做,同時保持它的訂購DateTimeSec

我想有這樣的事情的:

首先,我想從我的數據庫抓取數據表和value排序,然後:

//grab the interquartile range 
var sorted = a.AsEnumerable().Skip((int) (a.Rows.Count * 0.25)).Take((int) (a.Rows.Count * 0.50)).CopyToDataTable(); 
foreach (DataRow row in sorted) 
{ 
    row.ItemArray[1] += 10; 
} 

我的問題是什麼,然後我做用這個四分位數據表,我有嗎?有沒有更優雅的解決方案?

+0

更優雅?是。對錶格進行排序。然後找到第25和第75百分位。您的四分位距範圍> 0.25且<0.75。 – Kyle

回答

0

有沒有更優雅的解決方案呢?

是的。 Wikipedia page有公式可幫助您計算百分位數。

使用此函數在給定的百分比來計算的值:

private static double GetValueAtPercentile(double[] sequence, double percentile) 
{ 
    if (percentile > 1) 
     percentile = percentile * 0.01; 

    if (Math.Abs(percentile) > 1) 
     throw new ArgumentOutOfRangeException("cannot do calculate greater than 1 perc"); 

    Array.Sort(sequence); 
    var N = sequence.Length; 
    var n = (N - 1) * percentile + 1; 

    if (n == 1d) return sequence[0]; 
    else if (n == N) return sequence[N - 1]; 
    else 
    { 
     var k = (int)n; 
     var d = n - k; 
     return sequence[k - 1] + d * (sequence[k] - sequence[k - 1]); 
    } 
} 

現在用它在你的表:

var sequence = table.AsEnumerable().Select(s => s.Field<double>("value")); 
var firstQuartile = GetValueAtPercentile(sequence.ToArray(), 25); 
var thirdQuartile = GetValueAtPercentile(sequence.ToArray(), 75); 

foreach(DataRow row in table.Rows) 
{ 
    var rowValue = row.Field<double>("value"); 
    if(rowValue >= firstQuartile && rowValue <= thirdQuartile) 
    { 
     // Do things 
    } 
}