Python 提取值高于阈值的numpy数组的子数组
我有一个声音信号,作为numpy数组导入,我想把它切成块numpy数组。但是,我希望块只包含高于阈值的元素。例如:Python 提取值高于阈值的numpy数组的子数组,python,arrays,numpy,slice,Python,Arrays,Numpy,Slice,我有一个声音信号,作为numpy数组导入,我想把它切成块numpy数组。但是,我希望块只包含高于阈值的元素。例如: threshold = 3 signal = [1,2,6,7,8,1,1,2,5,6,7] 应该输出两个数组 vec1 = [6,7,8] vec2 = [5,6,7] 好的,上面是列表,但你明白我的意思 这是我到目前为止尝试过的,但这只会杀死我的公羊 def slice_raw_audio(audio_signal, threshold=5000): signal
threshold = 3
signal = [1,2,6,7,8,1,1,2,5,6,7]
应该输出两个数组
vec1 = [6,7,8]
vec2 = [5,6,7]
好的,上面是列表,但你明白我的意思
这是我到目前为止尝试过的,但这只会杀死我的公羊
def slice_raw_audio(audio_signal, threshold=5000):
signal_slice, chunks = [], []
for idx in range(0, audio_signal.shape[0], 1000):
while audio_signal[idx] > threshold:
signal_slice.append(audio_signal[idx])
chunks.append(signal_slice)
return chunks
这里有一个选择:
above_th = signal > threshold
index, values = np.arange(signal.size)[above_th], signal[above_th]
np.split(values, np.where(np.diff(index) > 1)[0]+1)
# [array([6, 7, 8]), array([5, 6, 7])]
在函数中换行:
def above_thresholds(signal, threshold):
above_th = signal > threshold
index, values = np.arange(signal.size)[above_th], signal[above_th]
return np.split(values, np.where(np.diff(index) > 1)[0]+1)
above_thresholds(signal, threshold)
# [array([6, 7, 8]), array([5, 6, 7])]
这里有一种方法-
def split_above_threshold(signal, threshold):
mask = np.concatenate(([False], signal > threshold, [False] ))
idx = np.flatnonzero(mask[1:] != mask[:-1])
return [signal[idx[i]:idx[i+1]] for i in range(0,len(idx),2)]
样本运行-
In [48]: threshold = 3
...: signal = np.array([1,1,7,1,2,6,7,8,1,1,2,5,6,7,2,8,7,2])
...:
In [49]: split_above_threshold(signal, threshold)
Out[49]: [array([7]), array([6, 7, 8]), array([5, 6, 7]), array([8, 7])]
运行时测试
其他办法-
# @Psidom's soln
def arange_diff(signal, threshold):
above_th = signal > threshold
index, values = np.arange(signal.size)[above_th], signal[above_th]
return np.split(values, np.where(np.diff(index) > 1)[0]+1)
# @Kasramvd's soln
def split_diff_step(signal, threshold):
return np.split(signal, np.where(np.diff(signal > threshold))[0] + 1)[1::2]
时间安排-
In [67]: signal = np.random.randint(0,9,(100000))
In [68]: threshold = 3
# @Kasramvd's soln
In [69]: %timeit split_diff_step(signal, threshold)
10 loops, best of 3: 39.8 ms per loop
# @Psidom's soln
In [70]: %timeit arange_diff(signal, threshold)
10 loops, best of 3: 20.5 ms per loop
In [71]: %timeit split_above_threshold(signal, threshold)
100 loops, best of 3: 8.22 ms per loop
以下是一种Numpythonic方法:
In [115]: np.split(signal, np.where(np.diff(signal > threshold))[0] + 1)
Out[115]: [array([1, 2]), array([6, 7, 8]), array([1, 1, 2]), array([5, 6, 7])]
请注意,这将为您提供所有基于拆分逻辑(基于diff
和continues items)的上下项目,它们始终是交错的,这意味着您可以通过索引将它们分开:
In [121]: signal = np.array([1,2,6,7,8,1,1,2,5,6,7])
In [122]: np.split(signal, np.where(np.diff(signal > threshold))[0] + 1)[::2]
Out[122]: [array([1, 2]), array([1, 1, 2])]
In [123]: np.split(signal, np.where(np.diff(signal > threshold))[0] + 1)[1::2]
Out[123]: [array([6, 7, 8]), array([5, 6, 7])]
您可以将列表中的第一项与阈值进行比较
,以找出上面哪一个片段将为您提供上面的项
通常,您可以使用以下代码段获取上面的项目:
np.split(signal, np.where(np.diff(signal > threshold))[0] + 1)[signal[0] < threshold::2]
np.split(信号,np.where(np.diff(信号>阈值))[0]+1)[信号[0]
如何定义块的大小?从大于阈值的第一个元素到最后一个元素。下一个块是相同的…您可以生成每个片,而不是返回所有内容,因此当迭代时,如果这是您唯一的问题,那么不是所有内容都在内存中。另外,您应该将信号数组转换为常规列表进行迭代,numpy只会使您的速度变慢。我们达到了相同的目标,但您的速度很快@上校:祝我好运。不过我应该更新答案。我猜OP只需要高于阈值的元素?@Divakar是的,这就是我提到要更新答案的原因。出了点问题,如果我将阈值设置为2000,列表的第一个元素是数组([2008],dtype=int16)。如果我看一下声音表,很明显,开始时有不止一个元素高于2000。@Qubix可能后面的那些元素与输入数组中的2008
信号?