假设我有一个名为a
的DataTable
,如下所示:
|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;
}
我的问题是我该如何处理我拥有的这个四分位数数据表?有没有更优雅的解决方案?
有没有更优雅的解决方案?
是的。 维基百科页面有公式来帮助你计算百分位数。
使用此函数计算给定百分位数的值:
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
}
}