在python中是否有任何有效的方法来计算一定数量的数组在某些间隔之间的次数?我将使用的间隔数量可能会非常大
像:
mylist = [4,4,1,18,2,15,6,14,2,16,2,17,12,3,12,4,15,5,17]
some function(mylist, startpoints):
# startpoints = [0,10,20]
count values in range [0,9]
count values in range [10-19]
output = [9,10]
答案 0 :(得分:4)
你必须至少迭代一次列表。
下面的解决方案适用于实现比较(<
,>
等)的任何序列/间隔,并使用bisect
算法在区间中找到正确的点,因此它是很快。
它可以使用浮点数,文本或其他任何东西。只需传递一个序列和一个间隔列表。
from collections import defaultdict
from bisect import bisect_left
def count_intervals(sequence, intervals):
count = defaultdict(int)
intervals.sort()
for item in sequence:
pos = bisect_left(intervals, item)
if pos == len(intervals):
count[None] += 1
else:
count[intervals[pos]] += 1
return count
data = [4,4,1,18,2,15,6,14,2,16,2,17,12,3,12,4,15,5,17]
print count_intervals(data, [10, 20])
将打印
defaultdict(<type 'int'>, {10: 10, 20: 9})
表示您有10个值&lt; 10和9值&lt; 20。
答案 1 :(得分:1)
如果数字是整数,如在您的示例中,将间隔表示为frozensets可能是最快的(值得尝试)。不确定间隔是否保证互相排斥 - 如果不是,那么
intervals = [frozenzet(range(10)), frozenset(range(10, 20))]
counts = [0] * len(intervals)
for n in mylist:
for i, inter in enumerate(intervals):
if n in inter:
counts[i] += 1
如果间隔是互斥的,那么这个代码可以在增量之后通过break
从内循环加速一点。然而,对于整数的互斥间隔> = 0,存在更具吸引力的选择:首先,准备辅助索引,例如,给定startpoints
数据结构可能
indices = [sum(i > x for x in startpoints) - 1 for i in range(max(startpoints))]
然后
counts = [0] * len(intervals)
for n in mylist:
if 0 <= n < len(indices):
counts[indices[n]] += 1
如果间隔可以,则可以调整这个值。 0(在这种情况下,所有内容都需要-min(startpoints)
补偿。
如果“数字”可以是任意浮点数(或decimal.Decimal
s等),而不仅仅是整数,则优化的可能性更受限制。是这样的吗??
答案 2 :(得分:1)
我不知道你的清单会有多大,但这是另一种方法。
import numpy as np
mylist = [4,4,1,18,2,15,6,14,2,16,2,17,12,3,12,4,15,5,17]
np.histogram(mylist, bins=[0,9,19])
答案 3 :(得分:0)
您还可以结合使用value_counts()和pd.cut()来帮助您完成工作。
import pandas as pd
mylist = [4,4,1,18,2,15,6,14,2,16,2,17,12,3,12,4,15,5,17]
split_mylist = pd.cut(mylist, [0, 9, 19]).value_counts(sort = False)
print(split_mylist)
这段代码将返回以下内容:
(0,10] 10 (10,20] 9 dtype:int64
然后,您可以使用to_list()函数获取所需的内容
split_mylist = split_mylist.tolist()
print(split_mylist)
输出:[10,9]