'Python: extracting specific values out an numpy array of indices

I have a numpy array of indices. For example:

 indices = np.array([0, 1, 2, 6, 7, 9, 12, 13, 14])

I would like to make an array

signals = np.zeros(np.amax(indices) + 1)

where I put a value of 2.0 for the beginning index of a sequence of the form: 0, 1, 2, 3 or 8, 9, 10, 11 (so where the value increases 1) and the last element of this sequence to be 3.0.

If the sequence is only a single number long (so no sequence) I would put the value 4.0 in this array.

So for the example given above the output should be [2.0, 0, 3.0, 0, 0, 0, 2.0, 3.0, 0, 4.0, 0, 0, 2.0, 0, 3.0].



Solution 1:[1]

This kind of issues, usually, can be handled by np.diff. We need to find starting and ending indices of each sequence; Also, the index of the value that is not in any sequences to be removed from indices that are found. At the end, the signals will be filled, in the specified indices, by the specified values:

# append is used for considering the last element
diff1 = np.diff(indices, prepend=indices[0]-2, append=indices[-1]+2)          # [2 1 1 4 1 2 3 1 1 2]
mask_start = diff1 != 1               # [ True False False  True False  True  True False False  True]
end = np.where(mask_start)[0] - 1     # [-1  2  4  5  8]

# correcting start mask for where a value is not in a sequence
mask4 = np.diff(end, prepend=end[0]-2) == 1
mask4_ind = end[mask4]
mask_start[mask4_ind] = False         # [ True False False  True False False  True False False  True]

# modifying the zero array
signals_copy = signals[indices]
signals_copy[mask_start[:-1]] = 2.0
signals_copy[end[1:]] = 3.0
signals_copy[mask4_ind] = 4.0
signals[indices] = signals_copy

This code is worked on your example and is tested on some others. You can cure this code if you encounter any probable shortcomings.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ali_Sh