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
tony selcuk
  • 709
  • 3
  • 11

3 Answers3

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
Kevin
  • 3,096
  • 2
  • 8
  • 37
  • This does not produce the posted expected result. The question asks for *consecutive* results, not total. – Woodford Apr 19 '21 at 22:18
  • ```np.diff``` will take the difference between consecutive elements. Could you give the expected output for the array ```a``` in my code snippet? – Kevin Apr 19 '21 at 22:22
  • The expected result is posted in the question. Run it yourself (hint, your code produces 19, 22, 18). – Woodford Apr 19 '21 at 22:41
  • The array posted in the question is unformatted :( – Kevin Apr 19 '21 at 22:42
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
Woodford
  • 3,746
  • 1
  • 15
  • 29
-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))
Masmoudi
  • 123
  • 1
  • 9