gpt4 book ai didi

python - 有没有更好的方法来删除长度等于或高于阈值的连续零部分?

转载 作者:行者123 更新时间:2023-12-04 16:35:37 28 4
gpt4 key购买 nike

问题陈述:

如标题所述,我想从一维数组中删除具有连续 长度等于或大于 的部分 < em>阈值。


我的解决方案:

我生成了以下 MRE 中所示的解决方案:

import numpy as np

THRESHOLD = 4

a = np.array((1,1,0,1,0,0,0,0,1,1,0,0,0,1,0,0,0,0,0,1))

print("Input: " + str(a))

# Find the indices of the parts that meet threshold requirement
gaps_above_threshold_inds = np.where(np.diff(np.nonzero(a)[0]) - 1 >= THRESHOLD)[0]

# Delete these parts from array
for idx in gaps_above_threshold_inds:
a = np.delete(a, list(range(np.nonzero(a)[0][idx] + 1, np.nonzero(a)[0][idx + 1])))

print("Output: " + str(a))

输出:

Input:  [1 1 0 1 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 1]
Output: [1 1 0 1 1 1 0 0 0 1 1]

问题:

是否有一种不那么复杂并且更有效的方法在 numpy 数组上执行此操作?


编辑:

根据@mozway 的评论,我正在编辑我的问题以提供更多信息。

基本上,问题域是:

  • 我有长度约为 20.000 个样本的一维信号
  • 部分信号因噪声而被调零
  • 信号的其余部分具有非零值,在 ~[50, 250] 范围内
  • 已删除前导和尾随零

我的目标是删除超过长度阈值的零部分,正如我已经说过的那样。

更详细的问题:

  • numpy 高效处理而言,是否有比上述解决方案更好的解决方案?
  • 高效信号处理技术而言,是否有比使用 numpy 更适合实现预期目标的方法?


对答案的评论:

关于我对高效 numpy 处理 的第一个担忧,@mathfux 的解决方案非常棒,基本上就是我一直在寻找的。这就是我接受这个的原因。

然而,@Jérôme Richard 的方法回答了我的第二个问题,它提供了一个非常高性能的解决方案;如果数据集非常大,这将非常有用。

感谢您的精彩回答!

最佳答案

np.delete 每次调用时都创建一个新数组,这是非常低效的。更快的解决方案是将所有值存储在掩码/ bool 数组中,然后立即过滤输入数组。但是,如果仅使用 Numpy 完成,这仍然可能需要纯 Python 循环。一个更简单、更快速的解决方案是使用 Numba(或 Cython)来做到这一点。这是一个实现:

import numpy as np
import numba as nb

@nb.njit('int_[:](int_[:], int_)')
def filterZeros(arr, threshold):
n = len(arr)
res = np.empty(n, dtype=arr.dtype)
count = 0
j = 0
for i in range(n):
if arr[i] == 0:
count += 1
else:
if count >= threshold:
j -= count
count = 0
res[j] = arr[i]
j += 1
if n > 0 and arr[n-1] == 0 and count >= threshold:
j -= count
return res[0:j]

a = np.array((1,1,0,1,0,0,0,0,1,1,0,0,0,1,0,0,0,0,0,1))
a = filterZeros(a, 4)
print("Output: " + str(a))

这是我机器上包含 100_000 个项目的随机二进制数组的结果:

Reference implementation: 5982    ms
Mozway's solution: 23.4 ms
This implementation: 0.11 ms

因此,该解决方案比初始解决方案快 54381,比 Mozway 的解决方案快 212 倍。通过就地(销毁输入数组)并告诉 Numba 该数组在内存中连续(使用: :1 而不是 :)。

关于python - 有没有更好的方法来删除长度等于或高于阈值的连续零部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70125699/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com