2017-06-13 142 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 
    } 
} 
相关问题