中位数的中位数 - 这是可能的还是有不同的方式

时间:2012-02-23 14:48:07

标签: javascript math aggregation median

目前我每天汇总大量数据,而且每天我都在计算当前值的中位数。现在我需要将所有这些每日结果汇总到每月,当然我需要再次计算中位数。

有没有办法计算中位数的中位数并使其统计正确?我想避免再次使用原始数据,因为它数量巨大:)

作为一个小概念证明我制作了这个javascript - 也许它有助于找到一种方法:

var aSortedNumberGroups = [];
var aSortedNumbers = [];
var aMedians = [];

Math.median = function(aData)
{
    var fMedian = 0;
    var iIndex = Math.floor(aData.length/2);
    if (!(aData.length%2)) {
        fMedian = (aData[iIndex-1]+aData[iIndex])/2;
    } else {
        fMedian = aData[iIndex];
    }

    return fMedian;
};

for (var iCurrGroupNum = 0; iCurrGroupNum < 5; ++iCurrGroupNum) {
    var aCurrNums = [];
    for (var iCurrNum = 0; iCurrNum < 1000; ++iCurrNum) {
        var iCurrRandomNumber = Math.floor(Math.random()*10001);
        aCurrNums.push(iCurrRandomNumber);
        aSortedNumbers.push(iCurrRandomNumber);
    }
    aCurrNums.sort(function(oCountA,oCountB) {
        return (iNumA < iNumB) ? -1 : 1;
    });
    aSortedNumberGroups.push(aCurrNums);
    aMedians.push(Math.median(aCurrNums));
}

console.log("Medians of each group: "+JSON.stringify(aMedians, null, 4));
console.log("Median of medians: "+Math.median(aMedians));
console.log("Median of all: "+Math.median(aSortedNumbers));

正如您将看到,所有原始数字的中位数和中位数的中位数之间通常存在巨大的上限,我希望它们彼此非常接近。

非常感谢!

4 个答案:

答案 0 :(得分:2)

你实际上没有“计算”你通过重新分配到子集来“发现”它的中位数,唯一的优化是可重新加载的“勾选图表”或运行记录:例如:通过这种方式存储每个事件的次数,您可以重新创建分布,而无需实际重新分析原始数据。这只是一个小的优化,但根据所讨论的数据集的重复,你可以节省大量的MB,至少是一堆处理器周期。

在JSON中考虑它:{ '1': 3, '5': 12, '7': 4 }规范:'1'发生了3次,'5'发生了12次,等等......

然后将这些计数保留在您想要获得中位数的时间段的开头。

希望这有助于确认

答案 1 :(得分:0)

不,遗憾的是,没有办法根据整体子集的中位数来计算中位数,但仍然具有统计学上的准确性。但是,如果你想计算均值,你可以使用子集的方法,因为它们的大小相等。

上面的ck优化可能对您有所帮助。

答案 2 :(得分:0)

另一种方法是获取每天的数据,解析数据并按排序顺序存储。在某一天,您只需查看中间数据,就可以得到答案。

在月末,您可以快速选择以查找中位数。您可以利用每天数据的排序顺序进行二分搜索以进行拆分。结果是您的月末处理将非常非常快。

同样类型的数据,以同样的方式组织,也可以让你以非常便宜的方式做各种百分位数。唯一困难的部分是提取每天的原始数据并对其进行排序。

答案 3 :(得分:0)

我知道这是一个非常过时的帖子,但未来的读者可能会发现Tukey的Ninther方法非常相关......分析在这里:http://www.johndcook.com/blog/2009/06/23/tukey-median-ninther/

-kg