Tengo algunos datos de audio cargados en una matriz numpy y deseo segmentar los datos encontrando partes silenciosas, es decir, partes donde la amplitud del audio está por debajo de un cierto umbral sobre aa período en el tiempo.Encontrar una gran cantidad de valores consecutivos cumpliendo la condición en una matriz numpy
Una forma muy sencilla de hacer esto es algo como esto:
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
El código anterior se encuentra partes donde hay al menos MIN_SILENCE elementos consecutivos más pequeños que SILENCE_THRESHOLD.
Ahora, obviamente, el código anterior es terriblemente ineficiente y un terrible abuso de expresiones regulares. ¿Hay algún otro método que sea más eficiente, pero aún así resulta en códigos igualmente simples y cortos?
¡Esto resulta en una impresionante aceleración de 20x! No tiene en cuenta la longitud mínima, pero eso es bastante fácil de agregar. El único problema es el aumento del uso de la memoria que hace que no sea factible su uso en alguna situación, así que creo que usaré esto de forma predeterminada y agregaré una opción para usar otro algoritmo cuando la memoria esté baja. – pafcu
Con numpy 1.9, obtengo un 'DeprecationWarning: numpy boolean resta (el operador binario) está en desuso' usando np.diff en la condición booleana. Reemplacé esta línea con 'd = np.subtract (condición [1:], condición [: - 1], dtype = np.float)' para evitar el problema. – daryl
@daryl - ¡Gracias por notar el cambio! Puede ser más claro hacer 'd = np.diff (condition.astype (int))' en su lugar, aunque eso es principalmente una cuestión de preferencia personal. –