finding continuous signal in noisy binary time series - python

Suppose I have a time series such as:
[1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 , 1, 1, 1, 1]
and I know there is some noise in the signal. I want to remove the noise as best I can and still output a binary signal. The above example would turn into something like:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 1, 1, 1, 1]
I have implemented a naive rule-based approach where I iterate through the values and have some minimum amount of 1s or 0s I need to "swap" the signal.
It seems like there must be a better way to do it. A lot of the results from googling around give non-binary output. Is there some scipy function I could leverage for this?

There are two similar functions that can help you: scipy.signal.argrelmin and scipy.signal.argrelmax. There are search for local min/max in discrete arrays. You should pass your array and neighbours search radius as order. Your problem can be solved by their combination:
>>> a = np.asarray([1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 , 1, 1, 1, 1], int)
>>> signal.argrelmin(a, order=3)
(array([4], dtype=int32),)
>>> signal.argrelmax(a, order=3)
(array([15], dtype=int32),)
Then you can just replace these elements.

Related

How to smooth list of numerical values in Python?

I have a collection of lists of integer values in python like the following:
[0, 0, 1, 0, 1, 0, 0, 2, 1, 1, 1, 2, 1]
Now I would like to have a somewhat "smoothed" sequence where each value with the same preceding and following value (which both differ from the central value in question) is replaced with this preceeding-following value. So my list above becomes:
[0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1]
(The order or procession is from left to right, just to reconcile possible conflicting groupings.)
How could I achieve list?
Bonus: same as above with possible parametrization how many preceeding-following values must occur to change the central value (2-2 or 3-3 instead of just 1-1).
A straightforward loop should do the trick:
_list = [0, 0, 1, 0, 1, 0, 0, 2, 1, 1, 1, 2, 1]
for i in range(1, len(_list)-1):
if _list[i-1] == _list[i+1]:
_list[i] = _list[i-1]
print(_list)
Output:
[0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1]
arr = [0, 0, 1, 0, 1, 0, 0, 2, 1, 1, 1, 2, 1]
res = [arr[0]]
i = 0
for i in range(1,len(arr)):
if res[i-1] not in arr[i:i+2]:
res.append(arr[i])
else:
res.append(res[i-1] )
print(res)
To allow the number of preceding / following values to be changed, you can create a 'pad' the list and iterate through a moving window on the padded list to check if all surrounding values are the same.
def smooth(lst, values=1, padding=None):
padded = [padding] * values + lst + [padding] * values
for i, n in enumerate(lst):
surrounding = set(padded[i:i+values] + padded[i+values+1:i+values*2+1])
if len(surrounding) == 1:
yield surrounding.pop()
else:
yield n
print(list(smooth([0, 0, 1, 0, 1, 0, 0, 2, 1, 1, 1, 2, 1]))) # [0, 0, 0, 1, 0, 0, 0, 2, 1, 1, 1, 1, 1]
If your input list may contain None, choose a different padding parameter when calling the generator.

Perform Delta Function between elements in PyTorch tensor

I have a 1 dimensional pyTorch tensor (dtype: int32) and was wondering if there was a way to perform a Dirac Delta function on the elements in this tensor, i.e:
f = tensor[1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1]
f_after_dirac_delta = tensor[0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1]
Thanks for any help in advance!
EDIT: as #GirishDattatrayHegde mentioned, the term Dirac-Delta was misleading. The correct term should have been a Kronecker-Delta. My apologies.
If I understand correctly, you want to compare successive elemeents of your tensor. This should work :
import torch
f = torch.tensor([1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1])
f_dirac = (f[1:] == f[:-1]).to(torch.long)

Program corresponding to Complete Boolean Lattice *Q_n*

I am first year student of Math faculty, and I didn't have programming class yet.
I am working on a project and to simplify my calculations it would be nice to implement a program that would calculate a matrix corresponding to the complete boolean lattice Q_n, which is a set of n integers from 1 to n and all of its possible subsets.
For example, when n=4 the matrix would be the following:
1;0;0;0;1;1;1;0;0;0;1;1;1;0;1
0;1;0;0;1;0;0;1;1;0;1;1;0;1;1
0;0;1;0;0;1;0;1;0;1;1;0;1;1;1
0;0;0;1;0;0;1;0;1;1;0;1;1;1;1
where first column correspond to the subset {1} of {1,2,3,4}, second column to subset {2} of {1,2,3,4}, column 5 for example to subset {1,2} of {1,2,3,4} and so on.
My idea was to create first all zero matrix of the corresponding size and then I do not know how to proceed. Please help me to get ideas.
The itertools module makes this easy. Here is one way:
import itertools
def subset_matrix(n):
A = [[0]*pow(2,n) for _ in range(n)]
j = 0
for k in range(n+1):
for c in itertools.combinations(range(n),k):
for i in c:
A[i][j] = 1
j += 1
return A
#for example:
A = subset_matrix(4)
for row in A:
print(row)
Output:
[0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1]
[0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1]
[0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1]
[0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1]

Progressively sort an array, like excel

I'd like to progressively sort an array, like I can in excel. For example:
randomMatrix = np.asarray(
[[0, 1, 0, 1, 0, 0, 2, 0, 1, 0],
[1, 0, 0, 0, 0, 1, 0, 0, 1, 2],
[1, 1, 0, 0, 2, 0, 0, 1, 0, 0]])
I'd like to have a: "Sort by column 1. Then, sort by column2. Then sort by column3, etc. etc." like we can in excel to produce the following:
sortedMatrix = np.asarray(
[[0, 1, 2, 0, 1, 0, 0, 1, 0, 0],
[0, 0, 0, 1, 1, 2, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 1, 1, 1, 2]])
How can I accomplish this? This answer recommends using lexsort, but when I do I get:
randomMatrix[np.lexsort(randomMatrix.T[::-1])]
array([[0, 1, 0, 1, 0, 0, 2, 0, 1, 0],
[1, 0, 0, 0, 0, 1, 0, 0, 1, 2],
[1, 1, 0, 0, 2, 0, 0, 1, 0, 0]])
You are sorting by rows which is different from the answer, which is sorting by column, a little adaptation of the answer should work for you:
randomMatrix[:, np.lexsort(randomMatrix)] # no need to transpose here but the sorting
# index has to be applied to the second axis
# array([[0, 1, 2, 0, 1, 0, 0, 1, 0, 0],
# [0, 0, 0, 1, 1, 2, 0, 0, 1, 0],
# [0, 0, 0, 0, 0, 0, 1, 1, 1, 2]])
Also from the documentation:
If a 2D array is provided for the keys argument, it's rows are
interpreted as the sorting keys and sorting is according to the last
row, second last row etc.
So here the last row will be the primary sorting key, the second row will be the secondary sorting key and the first row will be the last sorting key. And when actually doing sorting process, with a stable sorting algorithm, the sorting process will be executed on the first row firstly, then the second row and the primary sorting key will be sorted at the final stage. Combined together, np.lexsort returns an integer indices which gives the sorting order. Applying this sorting order to all the rows of your matrix gives the desired output.

Python Image.fromarray() doesn't accept my ndarray input which is built from a list

I'm trying to visualize a list of 2048280 integers which are either 1's or 0's. There is a function that outputs this list from a (width=1515 height=1352) image file. The function
test_results = [(numpy.argmax(SomeFunctionReturningAnArrayForEachGivenPixel))
for y in xrange(1352) for x in range(1532)]
returns an array of size 2058280 (=1515x1352) = as expected. For each y, 1532 values of 1/0 are returned and stored in the array.
Now, when this "test_results" array is returned, I want to save it as an image. So I np.reshape() the array to size (1352,1515,1). All is fine. Logically, I should save this list as a grayscale image. I changed the ndarray data type to 'unit8' and multiplied the pixel values by 127 or 255.
But no matter what I do, the Image.fromarray() function keeps saying that either 'it cannot handle this data type' or 'too many dimensions' or simply gives an error. When I debug it into the Image functions, it looks like the Image library cannot retrieve the array's 'stride'!
All the examples on the net simply reshape the list into an array and save them as an image! Is there anything wrong with my list?
I have already tried various modes ('RGB' , 'L' , '1'). I also changed the data type of my array into uint8, int8, np.uint8(), uint32..
result=self.evaluate(test_data,box) #returns the array
re_array= np.asarray(result,dtype='uint8')
res2 = np.reshape(reray,(1352,1515,1))
res3 =(res2*255)
i = Image.fromarray(res3,'1') ## Raises the exception
i.save('me.png')
For a grayscale image, don't add the trivial third dimension to your array. Leave it as a two-dimensional array: res2 = np.reshape(reray, (1352, 1515)) (assuming reray is the one-dimensional array).
Here's a simple example that worked for me. data is a two-dimensional array with type np.uint8 containing 0s and 1s:
In [29]: data
Out[29]:
array([[0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1],
[0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0],
[1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1],
[1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0],
[1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1],
[1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0],
[0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0],
[1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0],
[1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1],
[0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0]], dtype=uint8)
Create an image from 255*data with mode 'L', and save it as a PNG file:
In [30]: img = Image.fromarray(255*data, mode='L')
In [31]: img.save('foo.png')
When I tried to create the image using mode='1', I wasn't able to get a correct PNG file. Pillow has some known problems with moving between numpy arrays and images with bit depth 1.
Another option is to use numpngw. (I'm the author numpngw.) It allows you to save the data to a PNG file with bit depth 1:
In [40]: import numpngw
In [41]: numpngw.write_png('foo.png', data, bitdepth=1)

Categories