计算区间内的值数量

7 投票
4 回答
24549 浏览
提问于 2025-04-15 23:23

有没有什么高效的方法可以在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]

4 个回答

2

你还可以结合使用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]

5

我不知道你的列表会有多大,但这里有另一种方法。

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])
7

你至少需要遍历这个列表一次。

下面的解决方案适用于任何可以比较大小的序列或区间(比如用 <> 这样的符号),它使用了 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个值小于10,还有9个值小于20。

撰写回答