首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在numpy数组中查找满足条件的大量连续值

在numpy数组中查找满足条件的大量连续值
EN

Stack Overflow用户
提问于 2010-12-21 06:02:06
回答 8查看 14.1K关注 0票数 24

我有一些加载到numpy数组中的音频数据,我希望通过查找静默部分来分割数据,即音频幅度在一段时间内低于某个阈值的部分。

一种非常简单的方法是这样的:

values = ''.join(("1" if (abs(x) < SILENCE_THRESHOLD) else "0" for x in samples))
pattern = re.compile('1{%d,}'%int(MIN_SILENCE))                                                                           
for match in pattern.finditer(values):
   # code goes here

上面的代码查找至少有MIN_SILENCE个连续元素小于SILENCE_THRESHOLD的部分。

现在,很明显,上面的代码效率非常低,并且是对正则表达式的严重滥用。有没有其他更有效的方法,但仍然可以得到同样简单和简短的代码?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2010-12-21 08:11:32

这里有一个基于numpy的解决方案。

我认为(?)它应该比其他选项更快。希望这是相当清楚的。

但是,它需要的内存是各种基于生成器的解决方案的两倍。只要您可以在内存中保存数据的一个临时副本(对于diff),以及与您的数据长度相同的布尔数组(每个元素1位),它应该是非常有效的……

import numpy as np

def main():
    # Generate some random data
    x = np.cumsum(np.random.random(1000) - 0.5)
    condition = np.abs(x) < 1
    
    # Print the start and stop indices of each region where the absolute 
    # values of x are below 1, and the min and max of each of these regions
    for start, stop in contiguous_regions(condition):
        segment = x[start:stop]
        print start, stop
        print segment.min(), segment.max()

def contiguous_regions(condition):
    """Finds contiguous True regions of the boolean array "condition". Returns
    a 2D array where the first column is the start index of the region and the
    second column is the end index."""

    # Find the indicies of changes in "condition"
    d = np.diff(condition)
    idx, = d.nonzero() 

    # We need to start things after the change in "condition". Therefore, 
    # we'll shift the index by 1 to the right.
    idx += 1

    if condition[0]:
        # If the start of condition is True prepend a 0
        idx = np.r_[0, idx]

    if condition[-1]:
        # If the end of condition is True, append the length of the array
        idx = np.r_[idx, condition.size] # Edit

    # Reshape the result into two columns
    idx.shape = (-1,2)
    return idx

main()
票数 40
EN

Stack Overflow用户

发布于 2015-06-16 03:00:53

有一个使用scipy.ndimage的非常方便的解决方案。对于数组:

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

这可能是应用于另一个数组的条件的结果,查找连续区域就像下面这样简单:

regions = scipy.ndimage.find_objects(scipy.ndimage.label(a)[0])

然后,可以对这些区域应用任何函数,例如:

[np.sum(a[r]) for r in regions]
票数 8
EN

Stack Overflow用户

发布于 2010-12-21 07:53:43

如果您不介意使用scipy,请稍显马虎,但简单且快速:

from scipy.ndimage import gaussian_filter
sigma = 3
threshold = 1
above_threshold = gaussian_filter(data, sigma=sigma) > threshold

这个想法是,数据的安静部分将平滑到低振幅,而响亮的区域则不会。调整“sigma”将影响“安静”区域必须有多长时间;调整“阈值”将影响它必须有多安静。对于较大的sigma,这会减慢速度,此时使用基于FFT的平滑可能会更快。

这还有一个额外的好处,那就是单一的“热点像素”不会扰乱你的静音搜索,所以你对某些类型的噪音不那么敏感。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4494404

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档