一种有效的分位数算法/数据结构,允许样本随着时间的推移而增加?

mar*_*hon 8 java statistics quantile data-science

我正在寻找一种有效的分位数算法,该算法允许样本值随着时间的推移而“更新”或替换。

假设我有 items 的值1-n。我想将这些放入一个可以有效存储它们的分位数算法中。但是然后说在将来的某个时候, for 的值item-i会增加。我想删除原始值item-i并将其替换为更新后的值。特定用例适用于样本值随时间增加的流系统。

我见过的最接近这样的东西是t-Digest 数据结构。它有效地存储样本值。它唯一缺乏的是删除和替换样本值的能力。

我还查看了Apache Quantiles Datasketch - 它遇到了同样的问题 - 无法删除和替换样本。

编辑:更多地考虑这一点,不一定需要删除旧值并插入增加的值。如果存在只能更新值的约束,则可能有一种方法可以更轻松地重新计算内部状态。

Ale*_*rov 6

如果更新时间O(log n)和分位数计算时间O(log n)对您来说是可以接受的,那么解决方案之一是实现任何类型的自平衡二叉树(Splay treeAVL-treeRed-Black tree),同时保持HashMap<Key, Node>与树结构并行(或者,如果您知道您的键是例如数字0to n-1,那么您可以仅将数组用于相同目的)。您还需要为每个给定的节点保留子树中的节点数(这对于所有提到的自平衡树都是可能的 - 这是对节点进行更新的所有方法的一个小补充,例如旋转,等等。)。

使用密钥 K 更新值的伪代码,新值 V 将是:

Node node = find_node_in_hash_map_by_key(K); # O(1)
delete_node_keeping_subtree_counts_valid(node); # O(log n)
add_new_node_keeping_subtree_counts_valid(K, V); # O(log n)
Run Code Online (Sandbox Code Playgroud)

O(log n)由于每个节点中可用的子树大小,也可以获取分位数 q ,因为它几乎可以让您按O(log n)时间按大小访问第 i 个元素。该操作的伪代码如下所示:

# i-th element requested
node = root
while true:
    left = node.left_subtree
    left_count = 0
    if left is not None:
        left_count = left.nodes_count
    if i < left_count:
        node = left # select i-th element in the left subtree
    elif i == left_count:
        return node.value # we have exactly i elements in left subtree, so i-th value is in the current node
    else:
        i -= left_count + 1 # select element i - left_count - 1 from the right subtree
        node = node.right
Run Code Online (Sandbox Code Playgroud)

我不知道针对这种数据结构有一个好的开源 JAVA 解决方案,但是编写自己的 AVL 树并不是那么困难(而且 Splay 树应该是最简单的,只是它们最坏的情况复杂度不是O(log n),但平均而言它们应该好)。


Nic*_*oiu 0

我们可以保留一个从变量名到值的Map和一个SortedMap(搜索树),其键由值和名称组成(例如值+“_”+名称,或者具有这两个字段的Comparable对象),以便排序键也是排序后的值,但我们也可以拥有唯一的键,以便能够删除旧值+变量名并引入新值+变量名。这是 HBase 中使用的一种技术,与持久化 TreeMap(自平衡二叉搜索树)没有太大区别。

然后计算分位数或百分位数就是扫描结构的问题。

当更新率相对于分位数询问率低时,这是有效的。

当要求分位数的比率不是那么低时,我没有任何好的想法,也许还有一组堆结构,这种结构也以某种方式索引以使删除更有效,例如https://stackoverflow .com/questions/8705099/how-to-delete-in-a-heap-data-struction#:~:text=4%20Answers&text=Actually%2C%20you%20can%20remove%20an,parent%20of%20the% 20旧%20件.