Problem statement:
As stated by the title, I want to remove parts from an 1D array that have consecutive zeros and length equal or above a threshold.
My solution:
I produced the solution shown in the following 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))
Output:
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]
Question:
Is there a less complicated and more efficient way to do this on a numpy array?
Edit:
Based on @mozway comments, I'm editing my question providing some more information.
Basically, the problem domain is:
- I have 1D signals of length ~20.000 samples
- Some parts of the signals have been zeroed due to noise
- The rest of the signal has non-zero values, in the range ~[50, 250]
- Leading and trailing zeros have been removed
My goal is to remove the zero parts above a length threshold as I have already said.
More detailed questions:
- As far as numpy efficient handling is concerned, is there a better solution from the one above?
- As far as efficient signal processing techniques are concerned, is there more suitable way to achieve the desired goal than using numpy?
Comments on answers:
Regarding my first concern about efficient numpy handling, @mathfux's solution is really great and basically what I was looking for. That's why I accepted this one.
However, the approach by @Jérôme Richard answers my second question and it presents a really high performance solution; really useful if the dataset is extremely big.
Thanks for your great answers!