kynnemall
kynnemall

Reputation: 888

Split numpy array into sub-arrays when a sequence has a particular value on either end

I have a numpy array as follows:

array([0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.00791667, 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.06837452, 0.09166667, 0.00370881, 0.        ,
       0.        , 0.00489809, 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.23888889, 0.        , 0.05927778,
       0.12138889, 0.        , 0.        , 0.        , 0.36069444,
       0.31711111, 0.16333333, 0.15005556, 0.01      , 0.005     ,
       0.14357413, 0.        , 0.15722222, 0.29494444, 0.3245    ,
       0.31276639, 0.095     , 0.04750292, 0.09127039, 0.        ,
       0.06847222, 0.17      , 0.18039233, 0.21567804, 0.15913079,
       0.4579781 , 0.        , 0.2459    , 0.14886556, 0.08447222,
       0.        , 0.13722222, 0.28336984, 0.0725    , 0.077355  ,
       0.45166391, 0.        , 0.24892933, 0.25360062, 0.        ,
       0.12923041, 0.16145892, 0.48771795, 0.38527778, 0.29432968,
       0.31983305, 1.07573089, 0.30611111, 0.        , 0.0216475 ,
       0.        , 0.62268056, 0.16829156, 0.46239719, 0.6415958 ,
       0.02138889, 0.76457155, 0.05711551, 0.35050949, 0.34856278,
       0.15686164, 0.23158889, 0.16593262, 0.34961111, 0.21247575,
       0.14116667, 0.19414785, 0.09166667, 0.93376627, 0.12772222,
       0.00366667, 0.10297222, 0.173     , 0.0381225 , 0.22441667,
       0.46686111, 0.18761111, 0.56037889, 0.47566111])

From this array, I need to calculate the area under the curve for each sub-array where the first value is 0, where it goes above 0, and the last number should be the 0 after a non-zero number. Obviously the array lengths will vary. It may also occur that two of these sub-arrays will share a 0 value (the last 0 of the first array will be the fist 0 if the second array).

The expected first two arrays should be:

[0.        ,           0.00791667, 0.        ]
[0.        , 0.06837452, 0.09166667, 0.00370881, 0.        ]

I've tried and splitting python lists based on a character being equal to 0, but haven't found anything useful. What can I do?

Upvotes: 0

Views: 306

Answers (1)

Z Smith
Z Smith

Reputation: 252

See the code below - I think this is the most efficient you'll be able to do.

First, split the array using the indices of all of the zeroes. Where multiple zeroes are together, this produces several [ 0. ] arrays, so filter those out (based on length, as all arrays must necessarily begin with a zero) to produce C. Finally, since they all begin with zero, but none end with zero, append a zero to each array.

import numpy as np

# <Your array here>
A = np.array(...)

# Split into arrays based on zeroes
B = np.split(A, np.where(A == 0)[0])

# Filter out arrays of length 1
#  (just a zero, caused by multiple zeroes together)
f = np.vectorize(lambda a: len(a) > 1)
C = np.extract(f(B), B)

# Append a zero to each array
g = np.vectorize(lambda a: np.append(a, 0), otypes=[object])
D = g(C)

# Output result
for array in D:
    print(array)

This gives the following output:

[ 0.          0.00791667  0.        ]
[ 0.          0.06837452  0.09166667  0.00370881  0.        ]
[ 0.          0.00489809  0.        ]
[ 0.          0.23888889  0.        ]
[ 0.          0.05927778  0.12138889  0.        ]
[ 0.          0.36069444  0.31711111  0.16333333  0.15005556  0.01        0.005
  0.14357413  0.        ]
[ 0.          0.15722222  0.29494444  0.3245      0.31276639  0.095
  0.04750292  0.09127039  0.        ]
[ 0.          0.06847222  0.17        0.18039233  0.21567804  0.15913079
  0.4579781   0.        ]
[ 0.          0.2459      0.14886556  0.08447222  0.        ]
[ 0.          0.13722222  0.28336984  0.0725      0.077355    0.45166391
  0.        ]
[ 0.          0.24892933  0.25360062  0.        ]
[ 0.          0.12923041  0.16145892  0.48771795  0.38527778  0.29432968
  0.31983305  1.07573089  0.30611111  0.        ]
[ 0.         0.0216475  0.       ]
[ 0.          0.62268056  0.16829156  0.46239719  0.6415958   0.02138889
  0.76457155  0.05711551  0.35050949  0.34856278  0.15686164  0.23158889
  0.16593262  0.34961111  0.21247575  0.14116667  0.19414785  0.09166667
  0.93376627  0.12772222  0.00366667  0.10297222  0.173       0.0381225
  0.22441667  0.46686111  0.18761111  0.56037889  0.47566111  0.        ]

Upvotes: 3

Related Questions