0

How could I write a code that calculates how many consecutive times there was a positive , negative and zero values within the a array. How would I be able to compute this?

import numpy as np
a = np.array([  0.    0.    0.    0.    0.    0.    0.    0.    0.    0.    0.    0.
   0.    0.    0.    0.    0.    0.    0.    0.    0.   -8.    0.    0.
 304.2 -27.8 -15.4   0.    0.  -14.8   0.    6.4  14.4   0.  -10.6  55.8
  23.1   0.   27.9  34.7  62.   23.   41.6  30.7  30.5  34.9  40.9  21.7
  31.3  19.9  32.8  26.2  14.8  18.9  15.2  23.8  21.9 112.7  38.4  34.4])

Expected Result

Consecutive Positive results: 22
Consecutive Zero results: 21
Consecutive Negative results: 2
1
  • I am not trying to use a for loop if possible Commented Apr 19, 2021 at 22:03

3 Answers 3

2

You could use np.diff for this

a = np.array([0., -5., 4., -3., 0., -2.])
diff = np.diff(a)

print("Consecutive Positive results: ", np.count_nonzero(diff > 0))
print("Consecutive Zero results: ", np.count_nonzero(diff == 0))
print("Consecutive Negative results: ", np.count_nonzero(diff < 0))

Output:

Consecutive Positive results:  2
Consecutive Zero results:  0
Consecutive Negative results:  3

EDIT

Did not read the question properly. Here is my new attempt:

a = np.array([  0. ,   0. ,   0. ,   0. ,   0. ,   0. ,   0. ,   0. ,   0. ,
                0. ,   0. ,   0. ,   0. ,   0. ,   0. ,   0. ,   0. ,   0. ,
                0. ,   0. ,   0. ,  -8. ,   0. ,   0. , 304.2, -27.8, -15.4,
                0. ,   0. , -14.8,   0. ,   6.4,  14.4,   0. , -10.6,  55.8,
               23.1,   0. ,  27.9,  34.7,  62. ,  23. ,  41.6,  30.7,  30.5,
               34.9,  40.9,  21.7,  31.3,  19.9,  32.8,  26.2,  14.8,  18.9,
               15.2,  23.8,  21.9, 112.7,  38.4,  34.4])

sign = np.sign(a) # we only care about the sign

# find runs, cred to https://stackoverflow.com/a/54597990/14923227
def count_consecutive(arr, n):
    # pad a with False at both sides for edge cases when array starts or ends with n
    d = np.diff(np.concatenate(([False], arr == n, [False])).astype(int))
    # subtract indices when value changes from False to True from indices where value changes from True to False
    return np.flatnonzero(d == -1) - np.flatnonzero(d == 1)

print("Consecutive Positive results: ", np.max(count_consecutive(sign, 1)))
print("Consecutive Zero results: ", np.max(count_consecutive(sign, 0)))
print("Consecutive Negative results: ", np.max(count_consecutive(sign, -1)))

Output:

Consecutive Positive results:  22
Consecutive Zero results:  21
Consecutive Negative results:  2
Sign up to request clarification or add additional context in comments.

4 Comments

This does not produce the posted expected result. The question asks for consecutive results, not total.
np.diff will take the difference between consecutive elements. Could you give the expected output for the array a in my code snippet?
The expected result is posted in the question. Run it yourself (hint, your code produces 19, 22, 18).
The array posted in the question is unformatted :(
0

It seems numpy doesn't have a build-in groupby function that would make this a little simpler, but we can use itertools.groupby instead. The idea is to use groupby to combine consecutive elements satisfying some condition (positive, negative, or zero) and then find the largest of those groups.

>>> a = np.array([
    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,
    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,   -8.,    0.,    0.,
  304.2, -27.8, -15.4,   0.,    0.,  -14.8,   0.,    6.4,  14.4,   0.,  -10.6,  55.8,
   23.1,   0.,   27.9,  34.7,  62.,   23.,   41.6,  30.7,  30.5,  34.9,  40.9,  21.7,
   31.3,  19.9,  32.8,  26.2,  14.8,  18.9,  15.2,  23.8,  21.9, 112.7,  38.4,  34.4
])
>>> max(map(len, (list(g) for k, g in itertools.groupby(a>0) if k)))
22
>>> max(map(len, (list(g) for k, g in itertools.groupby(a==0) if k)))
21
>>> max(map(len, (list(g) for k, g in itertools.groupby(a<0) if k)))
2

Comments

-1
import numpy as np
a = np.array([0., -5., 4., -3., 0., -2.])
x = (a > 0).sum()
y = (a == 0).sum()
z = (a < 0).sum()
print("Consecutive Positive results: "+ str(x))
print("Consecutive Zero results: "+ str(y))
print("Consecutive Negative results: "+ str(z))

3 Comments

Is there a more optimized way without using a for loop, hence why I used numpy to begin with. Thanks anyways
here i updated the answer, no more loop
This does not produce the posted expected result. The question asks for consecutive results, not total.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.