4

If it exists in numpy a function which calculates a maximum length of consecutive numbers in 3d array along a chosen axis?

I created such function for 1d array (the function's prototype is max_repeated_number(array_1d, number)):

>>> import numpy
>>> a = numpy.array([0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0])
>>> b = max_repeated_number(a, 1)
>>> b
4

And I want to applicate it for 3d array along axis=0.

I do for a 3d array of following dimentions (A,B,C):

result_array = numpy.array([])
for i in range(B):    
     for j in range(C):
          result_array[i,j] = max_repeated_number(my_3d_array[:,i,j],1)

But the time of calculation is very long because of the loops. I know that one need to avoid the loops in python.

If it exists a way to do it without loops?

Thanks.

PS: Here is the code of max_repeated_number(1d_array, number):

def max_repeated_number(array_1d,number):
    previous=-1
    nb_max=0
    nb=0
    for i in range(len(array_1d)):
        if array_1d[i]==number:
            if array_1d[i]!=previous:
                nb=1
            else:
                nb+=1
        else:
            nb=0

        if nb>nb_max:
            nb_max=nb

        previous=array_1d[i]
    return nb_max
natalia
  • 309
  • 2
  • 11
  • 3
    Why don't you show us the code for max_repeated_number and we might be able to show you how to extend it – YXD Nov 05 '13 at 13:17
  • 1
    See also (for 1d case): [find length of sequences of identical values in a numpy array](http://stackoverflow.com/q/1066758/1730674) and [find the length of the longest consecutive series of numbers](http://stackoverflow.com/q/16733236/1730674) – askewchan Nov 05 '13 at 14:45
  • @MrE, I have just added the code of max_repeated_number. – natalia Nov 05 '13 at 16:29
  • 1
    @askewchan, thanks! But i need for 3d array... – natalia Nov 05 '13 at 16:34
  • I understand, but you could probably improve your speed a lot by using one of those solutions for your 1d function. – askewchan Nov 05 '13 at 17:30

1 Answers1

3

You can adapt the solution explained here for any ndarray case using something like:

def max_consec_elem_ndarray(a, axis=-1):
    def f(a):
        return max(sum(1 for i in g) for k,g in groupby(a))
    new_shape = list(a.shape)
    new_shape.pop(axis)
    a = a.swapaxes(axis, -1).reshape(-1, a.shape[axis])
    ans = np.zeros(np.prod(a.shape[:-1]))
    for i, v in enumerate(a):
        ans[i] = f(v)
    return ans.reshape(new_shape)

Example:

a = np.array([[[[1,2,3,4],
                [1,3,5,4],
                [4,5,6,4]],
               [[1,2,4,4],
                [4,5,3,4],
                [4,4,6,4]]],

              [[[1,2,3,4],
                [1,3,5,4],
                [0,5,6,4]],
               [[1,2,4,4],
                [4,0,3,4],
                [4,4,0,4]]]])

print(max_consec_elem_ndarray(a, axis=2))
#[[[ 2.  1.  1.  3.]
#  [ 2.  1.  1.  3.]]
# 
# [[ 2.  1.  1.  3.]
#  [ 2.  1.  1.  3.]]]
Community
  • 1
  • 1
Saullo G. P. Castro
  • 56,802
  • 26
  • 179
  • 234