我正在对数百GB的数据进行大规模分析,但它是流式的,我想要最有效的解决方案来计算模式和百分位数。我现在如何做到这一点是将数字(以小数点为单位的ping时间,如55.4381或33.97818)四舍五入到最接近的十分之一位置,并在字典中记录这些出现次数。例如:
a = {48.8: 5, 42.3: 24, 56.1: 3}
我发现这是满足我需求的最佳方式,同时仍然保持内存效率。我想到的最佳方法是使用有序字典,计算字典中的键数,并按排序顺序获取第k个键。因此,如果有意义的话,获得上述数据的第50个百分位将为a[(32*0.5)-1] -> a[15] -> 42.3
。基本上抓住列表的第k个元素,如果所说的列表是[42.3, 42.3, ..., 42.3, 48.8, 48.8, 48.8, 48.8, 48.8, 56.1, 56.1, 56.1]
,但不需要为该列表分配内存。
所以,我想知道是否有人对最有效的方法有任何想法。我目前正在使用Python 3.5.2。谢谢你的阅读。
答案 0 :(得分:0)
# We want this percentile.
pct = 0.25
# Data.
a = {48.8: 5, 42.3: 24, 56.1: 3}
# Find that percentile in this data.
def pctile(a, pct):
# Convert to list of tuples, sort
LofT = list(a.items())
LofT.sort()
# Sum of counts.
ct = sum(a.values())
# Index corresponding to percentile. Don't subtract 1; e.g. ct = 100,
# 25th pctile, 25% are below, we want index 25, below which there are
# 25 values. But do round to nearest integer.
pcti = int(ct * pct + 0.5)
# Traverse sorted list until this index is reached.
for v, c in LofT:
pcti -= c
if pcti < 0:
return v
# Still here? Then pct was >= 1, just return the maximum value.
return LofT[-1][0]
由于排序步骤,时间复杂度为O( n log n ),其中 n = len(a)
。