Python—加快查找大于阈值的集合的百分比

Python—加快查找大于阈值的集合的百分比,python,cython,Python,Cython,我需要找出一组数字中哪个百分比超过阈值。有没有办法加快速度?我的实现对于预期的应用程序来说太慢了。如果这改变了什么,我将使用mpirun-np 100 python program.py运行我的程序。我不能使用numba,因为这个程序的其余部分使用try/except语句 import numpy as np my_vals = [] threshold_val = 0.065 for i in range(60000): my_vals.append(np.random.normal(

我需要找出一组数字中哪个百分比超过阈值。有没有办法加快速度?我的实现对于预期的应用程序来说太慢了。如果这改变了什么,我将使用
mpirun-np 100 python program.py
运行我的程序。我不能使用numba,因为这个程序的其余部分使用try/except语句

import numpy as np
my_vals = []
threshold_val = 0.065
for i in range(60000):
    my_vals.append(np.random.normal(0.05, 0.02))

for i in np.arange(0,100,0.001):
    if np.percentile(my_vals,i) > threshold_val:
        perc = 1*i
        break
else: perc = 100
由于高斯(正态)分布产生钟形曲线,您应该能够计算出最佳概率最高的百分位,然后首先编写代码进行检查,然后使用改进的二进制搜索找到最佳最低阈值

例如,如果您确定您的参数最有可能有利于例如17.951(这只是一个示例,我实际上没有费心计算它),那么从该点附近开始,而不是从0开始。将其视为二进制搜索-从下限0开始,上限100.0开始,并将点设置为将列表平分为分布的最佳百分位数

如果当前上限超过
阈值
,则将下半部分平分,以找到匹配的最低值;如果未超过阈值,则将上半部分等分,以此类推。例如,在0.000到100.000的范围内,如果从17.951开始并发现其未超过阈值,则将边界调整为17.952到100.000,然后尝试58.976(中间)。一旦找到高于阈值的值,就使用该值作为上限(因为它是非最佳答案)。继续此过程,直到上下限相距0.001,这将为您提供最佳答案。平均而言,您应该运行大约17个测试,而不是100000个

您还可以自动计算最佳值,以防正态分布发生变化,因为正态分布会生成钟形曲线,并且您将知道基于参数的钟形曲线的统计信息

您的解决方案只需要找到百分比高于阈值的最低值,因此此方法应尽量减少需要检查的样本数


还有一个提示:np.percentile必须在代码中对my_vals进行100000次排序;我不知道预排序列表是否有帮助,但它可能值得检查(您可能需要测试几个可能的排序参数,因为它似乎没有记录在排序的方向上)。

您可以通过对值进行排序并搜索超出阈值的第一个值,直接找到解决方案。百分位是此元素前面的数组值的分数:

import numpy as np
my_vals = []
threshold_val = 0.065
for i in range(60000):
    my_vals.append(np.random.normal(0.05, 0.02))

from bisect import bisect_right

print bisect_right(sorted(my_vals),threshold_val)/float(len(my_vals))*100

如果代码正常工作,那么最好在代码审查中发布。他们在这方面有一点天赋。这里也有一些很好的反馈。我使用np.random.normal生成了一个数字示例集-我的真实数字集是不同的。如果不清楚的话,很抱歉。没关系,您仍然可以在运行时计算近似的最佳中点,因为钟形曲线是可预测的,并且不必精确,因为您应该能够将测试数量从100000减少到20以下。或者,您可以从50000开始作为明显的中间点,看看二进制搜索方法是否足够快,如果不够快,看看是否可以优化起始位置。