python - 在距离最小的列表中找到 N 个最大的元素

标签 python numpy scipy

我想从列表中提取 N 个最大的元素,但我希望对任意两个元素都提取 x[i]x[j] , abs(i-j) > min_distance .

scipy.signal.find_peaks(x, distance=min_distance)提供此功能。但是我需要重复此操作数百万次,并且我正在尝试加快操作速度。

我注意到 find_peaks不接受参数 N指示要提取的峰数。它还不允许从最大到最小返回峰值,需要额外调用 l.sort()l = l[:N] .

我尝试编写一个惰性排序器,它只查找 N 个最大的元素而不对列表的其余部分进行排序。

得到以下结果here我选择了 heapq .这是我的尝试:

import heapq

def new_find_peaks(x, N, min_distance=0):
    x = enumerate(x)

    x = [(-val,i) for (i,val) in x]
    heapq.heapify(x)

    val, pos = heapq.heappop(x)
    peaks = [(-val, pos,)]

    while len(peaks)<N:

        while True:
            val, pos = heapq.heappop(x)
            d = min([abs(pos - pos_i) for _,pos_i in peaks])
            if d >= min_distance:
                break

        peaks.append((-val, pos,))

    return map(list, zip(*peaks)) #Transpose peaks into 2 lists

然而,这仍然比 find_peaks 慢 20 倍,可能是由于 find_peaks CPython 实现。另外,我注意到几乎一半的时间花在了

x = [(-val,i) for (i,val) in x]

你有什么更好的办法来加快这个操作吗?

--- 最小的可重现示例 ---

例如:

x = [-8.11, -7.33, -7.48, -5.77, -8.73, -8.73, -7.02, -7.02,
 -7.80, -10.92, -9.36, -9.83, -10.14, -10.77, -11.23, -9.20,
 -9.52, -9.67, -11.23, -9.98, -7.95, -9.83, -8.89, -7.33,
 -4.20, -4.05, -6.70, -7.02, -9.20, -9.21]

new_find_peaks(x, N=3, min_distance=5)

>> [[-4.05, -5.77, -7.8], [25, 3, 8]]

x

请注意 x[24]是-4.2,但由于x[25]更大并且25-24 < min_distance , 这被丢弃了。另请注意 x[8]不是真正的峰值,因为 x[7]更大,但由于与 x[3] 的距离而被丢弃.这是预期的行为。

最佳答案

用 Python 改进您的代码可能会给您带来一些改进,但由于您的代码看起来很干净并且算法的想法很合理,我认为您不会用 Python 方法击败 find_peaks

因此,我建议您使用更接近金属的语言编写您自己的库,如果您需要 python 中的结果,则编写您自己的 python 包装器。例如,您可以使用 Swift。 Here是 Swift 中堆队列的实现,here你发现描述了一种与 python 交互的方法。

连接点留作练习。 ;)

关于python - 在距离最小的列表中找到 N 个最大的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57771138/

相关文章:

python - 如何在 Python 中通过替换生成排列

python - RedHat 上 Scipy 和 Scikit-learn 中的 undefined symbol

python - 具有单位矩阵和正则矩阵的高效 Kronecker 积 - NumPy/Python

python - 将 HOCR 输出转换为字符串(用于正则表达式)的策略是什么?

python - 如何找出 Pandas 中使用的编码

python - 如何将 scipy.stats.describe 应用于每个组?

python - 如何在 numpy/scipy/pandas 中生成匹配的矩阵/数组?

Python如何在字典中查找重复值

Python:matplotlib 'numpy.ndarray' 对象没有属性 'has_data'

python - 水平连接numpy向量和矩阵