Python: максимальная длина последовательных чисел в трехмерном массиве вдоль выбранной оси

Если в numpy существует функция, которая вычисляет максимальную длину последовательных чисел в трехмерном массиве вдоль выбранной оси?

Я создал такую ​​функцию для массива 1d (прототип функции - max_repeated_number(array_1d, число)):

>>> 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

И я хочу применить его для трехмерного массива вдоль оси = 0.

Я делаю для трехмерного массива следующих размеров (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)

Но время расчета очень велико из-за циклов. Я знаю, что нужно избегать петель в python.

Если существует способ сделать это без циклов?

Спасибо.

PS: Вот код max_repeated_number (1d_array, число):

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

person natalia    schedule 05.11.2013    source источник
comment
Почему бы вам не показать нам код для max_repeated_number, и мы могли бы показать вам, как его расширить   -  person YXD    schedule 05.11.2013
comment
@MrE, я только что добавил код max_repeated_number.   -  person natalia    schedule 05.11.2013
comment
@askewchan, спасибо! Но мне нужен 3D-массив...   -  person natalia    schedule 05.11.2013
comment
Я понимаю, но вы, вероятно, могли бы значительно улучшить свою скорость, используя одно из этих решений для своей функции 1d.   -  person askewchan    schedule 05.11.2013


Ответы (1)


Вы можете адаптировать описанное здесь решение для любого ndarray случая, используя что-то вроде:

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)

Пример:

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.]]]
person Saullo G. P. Castro    schedule 05.11.2013