Python - 从(扩展)字典中获取 select 第 k 个值的最有效方法
Python - Most efficient way to select kth value from (expanded) dictionary
我正在对数百 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。感谢阅读。
# 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)
,由于排序步骤。
我正在对数百 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。感谢阅读。
# 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)
,由于排序步骤。