0

Hello I have a numpy array as follows:

list_of_values = [-0.5, -0.8, -0.6, -0.2, 0.2, 0.5, 0.7, 0.9, -0.3, 0.2, 0.6, 0.4, 0, 0.2, 0, -0.3, -0.2, 0, -0.6, 0, 0.3]
array= np.array(list_of_values)

I need an array of the same size, having a 1 when the value goes from negative to positive, and a -1 when the value goes from positive to negative, and a 0 for the rest. If there is a 0 in list_of_values, and it bounces back, it should not be considered as the 0 line has been crossed.

This is the exact output that I am looking for

output = [0, 0, 0, 0, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1]

The real list_of_values is large, with 3000+ numbers, so the solution should use Numpy (some for loop is not valid), and it should be quick.

Thank you

2 Answers 2

1

You can use numpy.ediff1d:

>>> import numpy as np
>>> arr = np.array([-1, -0.8, -0.6, -0.1, 0.1, 0.5, 0.7, 1, -0.3, 0.2, 0.6])
>>> np.ediff1d(np.sign(arr), to_begin=0) // 2
array([ 0.,  0.,  0.,  0.,  1.,  0.,  0.,  0., -1.,  1.,  0.])

If you'd like to consider 0 as positive:

>>> arr = np.array([-1, -0.8, -0.6, -0.1, 0.0, 0.5, 0.7, 1, -0.3, 0.2, 0.6])
>>> np.ediff1d(np.where(arr==0, 1, np.sign(arr)), to_begin=0)//2
array([ 0.,  0.,  0.,  0.,  1.,  0.,  0.,  0., -1.,  1.,  0.])

EDIT

Based on your edit, you can do the following:

>>> arr = [-0.5, -0.8, -0.6, -0.2, 0.2, 0.5, 0.7, 0.9, -0.3, 0.2, 0.6, 0.4, 0, 0.2, 0, -0.3, -0.2, 0, -0.6, 0, 0.3]
>>> output = np.array(arr)
>>> nonzero_idx = output != 0
>>> nonzero_arr = output[nonzero_idx]
>>> res = np.ediff1d(np.sign(nonzero_arr), to_begin=0) // 2
>>> output[nonzero_idx] = res
>>> output
array([ 0.,  0.,  0.,  0.,  1.,  0.,  0.,  0., -1.,  1.,  0.,  0.,  0.,
        0.,  0., -1.,  0.,  0.,  0.,  0.,  1.])
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your answer I really appreciate it. What if I wanted to treat 0 as indifferent, meaning that if [..., +, 0, +, ...], the third value would not be -1, and the other way around, if [..., -, 0, -, ....], the third value would not be +1
Well actually I didn't know what you wanted in case of 0. Could you add an input with 0 and expected output in your question? I can update the answer accordingly.
0

The answer provided by Cyttorak is correct and a lot prettier than mine, however, if you don't mind a little bit uglier code and want speed, this is faster.

a2 = np.array([-1, 1])
array = np.array([-1, -0.8, -0.6, -0.1, 0.1, 0.5, 0.7, 1, -0.3, 0.2, 0.6])
array = np.where(array >= 0, -1, 1)
output = np.convolve(array, a2, mode='same')
output = np.where((output == 2) | (output == -2), output, 0) // 2

Edit: sorry, forgot to copy-paste a2 :D

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.