Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 查找间隔中的数字频率_Python_Python 3.x_Algorithm_Data Structures_Intervals - Fatal编程技术网

Python 查找间隔中的数字频率

Python 查找间隔中的数字频率,python,python-3.x,algorithm,data-structures,intervals,Python,Python 3.x,Algorithm,Data Structures,Intervals,找到非重叠间隔内元素的频率/计数的最有效方法是什么?例如: limits = [0, 25, 40, 60] data = [15, 5, 2, 56, 45, 23, 6, 59, 33, 18] 对于上面的列表,我想找出数据中两个相邻限制内的元素数量。因此,对于上述情况,计数将类似于: 0-25:6; 25-40: 1; 40-60: 3; 我所能想到的就是时间上的O(n^2)。有更好的方法吗?我向您推荐这种方法,它按照O(nlogn) 我展示了每个重要行的时间复杂度,以计算代码的总时间复

找到非重叠间隔内元素的频率/计数的最有效方法是什么?例如:

limits = [0, 25, 40, 60]
data = [15, 5, 2, 56, 45, 23, 6, 59, 33, 18]
对于上面的列表,我想找出数据中两个相邻限制内的元素数量。因此,对于上述情况,计数将类似于:

0-25:6; 25-40: 1; 40-60: 3;


我所能想到的就是时间上的O(n^2)。有更好的方法吗?

我向您推荐这种方法,它按照O(nlogn)

我展示了每个重要行的时间复杂度,以计算代码的总时间复杂度。代码的总时间复杂度等于
O((n+m)log(n+m))
,可显示为
O(nlogn)

改进 如果您对输入有一些假设,您可以改进它。如果您有关于
限制范围
数据
的信息,则可以将排序算法更改为。计数排序的时间复杂度被认为是
O(n)
,代码的总时间复杂度将是
O(n)

这里是一种简单的
O(NlogN)
方法。对数据进行排序,然后使用双指针方法将每个元素放置在正确的间隔内

limits=[0,25,40,60]
数据=[15,5,2,56,45,23,6,59,33,18]
data.sort()
n、 m=len(数据),len(限值)
计数=[0]*(m-1)
#计数[i]表示极限[i]和极限[i+1]之间的计数
low=0#我们目前正在检查的区间指数较低
ptr=0
当ptr=限制[低]且i=限制[低]:
如果低==len(限值)-1:
打破
低+=1
打印(计数)
限制=[0,25,40,60,80]
数据=[15,5,2,56,45,23,6,59,33,18,25,45,85]
dict_data={}
i=0
计数=1
当i
您可以使用计数器(来自集合)来管理理货和对分以分类:

from collections import Counter
from bisect import bisect_left

limits = [0, 25, 40, 60, 80]
data   = [15, 5, 2, 56, 45, 23, 6, 59, 33, 18]

r = Counter(limits[bisect_left(limits,d)-1] for d in data)

print(r)
Counter({0: 6, 40: 3, 25: 1})

它的时间复杂度为O(NLogM),其中M是极限中断的数量,N是数据项的数量

不需要计数器计数,因为已知存储箱的数量,将dict交换到阵列访问以进行存储箱

从对分导入对分\u右
def bin_it(限制、数据):
“根据(升序)限制的Bin数据。”
垃圾箱=[0]*(len(限制)+1)#还添加了低于/超过范围的垃圾箱
对于数据中的d:
箱子[对分_右(极限,d)]+=1
回收箱
如果名称=“\uuuuu main\uuuuuuuu”:
极限=[0,25,40,60]
数据=[15,5,2,56,45,23,6,59,33,18]
bins=bin_it(限制、数据)
打印(f“<{limits[0]:2}:”,箱子[0])
对于lo、hi,在zip中计数(限制、限制[1:],箱子[1:]):
打印(f“>={lo:2}..<{hi:2}:”,计数)
打印(f“>={limits[-1]:2}…:”,箱子[-1])
"""
样本输出:
<  0 : 0
>=  0 .. < 25 : 6
>= 25 .. < 40 : 1
>= 40 .. < 60 : 3
>= 60 ...     : 0
"""

为什么不使用numpy.histogram方法和应该使用的bins参数?@GirishSrivatsa会喜欢使用numpy或pandas,但必须使用纯python数据结构etcSort
data
,然后进行线性遍历。简单
O(NlogN)
approach根据无权重的numpy直方图方法,该算法将数据拼接成大小为B=65536的块,并通过排序算法对每个块进行排序(numpy使用B排序,您可以使用自己的排序),然后对块执行线性遍历,检测直方图的边缘(已排序)然后根据总尺寸(B)的插入位置计算频率
limits = [0, 25, 40, 60, 80]
data = [15, 5, 2, 56, 45, 23, 6, 59, 33, 18, 25, 45, 85]
dict_data = {}
i = 0
count = 1
while i < len(limits)-1:
    for j in data:
        if j in range(limits[i], limits[i+1]):
            if '{}-{}'.format(limits[i],limits[i+1]) in dict_data:
                dict_data['{}-{}'.format(limits[i],limits[i+1])] +=count
            else:
                dict_data['{}-{}'.format(limits[i],limits[i+1])] = count
        
    i+=1
print(dict_data)
from collections import Counter
from bisect import bisect_left

limits = [0, 25, 40, 60, 80]
data   = [15, 5, 2, 56, 45, 23, 6, 59, 33, 18]

r = Counter(limits[bisect_left(limits,d)-1] for d in data)

print(r)
Counter({0: 6, 40: 3, 25: 1})