Как я могу вернуть самое длинное непрерывное вхождение True в Boolean и заменить другое True на False? - PullRequest
3 голосов
/ 25 мая 2019

Я пытаюсь вернуть логическое значение, которое дает только самое длинное «Истинное» вхождение в исходном логическом значении, и заменить более короткие «Истинные» блоки на «Ложные».Пример a = [True, True, False, True, True, True, False], я хочу вернуть [False, False, False, True, True, True, False].

я пробовал more_itertools и этокажется, есть некоторые интересные функции, но не уверен, как именно реализовать для моих целей.

a=[True, True, False, True , True, True, False]

pred = lambda x: x in {True}

p=list(mit.run_length.encode(a))

>>>
Results in: (True,2),(False,1),(True,3),(False,1)

Итак, что я хочу в итоге автоматически получить, это (False, 3), (True, 3), (False, 1).какие-либо предложения?Спасибо за вашу помощь

Ответы [ 2 ]

3 голосов
/ 25 мая 2019

Ниже решение должно работать после использования more_itertools.run_length .

По сути, логика состоит в том, чтобы найти длину самой длинной подпоследовательности True и расположение этого индекса в result списке
затем подсчитайте общее количество элементов до и после этой самой длинной подпоследовательности, а затем составьте результирующий список кортежей соответственно.

import more_itertools as mit

a=[True, True, False, True , True, True, False]

result = list(mit.run_length.encode(a))

#Find the length of longest subsequence of True, and the location if that index in result
max_true_count = -1
max_true_idx  = -1
for idx, (val, count) in enumerate(result):
    if val and max_true_count < count:
        max_true_count = count
        max_true_idx = idx

#Find total elements before and after the longest subsequence tuple
elems_before_idx = sum((idx[1] for idx in result[:max_true_idx]))
elems_after_idx = sum((idx[1] for idx in result[max_true_idx+1:]))

#Create the output list using the information
output = [(False, elems_before_idx), (True, max_true_count), (False, elems_after_idx)]
print(output)

Выход будет

[(False, 3), (True, 3), (False, 1)]
1 голос
/ 25 мая 2019

Вот векторизованный -

def keep_longest_true(a):
    # Convert to array
    a = np.asarray(a)

    # Attach sentients on either sides w.r.t True
    b = np.r_[False,a,False]

    # Get indices of group shifts
    s = np.flatnonzero(b[:-1]!=b[1:])

    # Get group lengths and hence the max index group
    m = (s[1::2]-s[::2]).argmax()

    # Initialize array and assign only the largest True island as True.
    out = np.zeros_like(a)
    out[s[2*m]:s[2*m+1]] = 1
    return out

def island_info(a):
    '''' Get island tuple info
    '''

    # Attach sentients on either sides w.r.t array start and end
    b = np.r_[~a[0],a,~a[-1]]

    # Get group lengths and group start elements
    lens = np.diff(np.flatnonzero(b[:-1] != b[1:]))
    grpID = np.resize([a[0],~a[0]],len(lens))

    # zip those two info for final o/p
    return zip(grpID,lens)

Пробный прогон -

In [221]: a
Out[221]: [True, True, False, True, True, True, False]

In [222]: keep_longest_true(a)
Out[222]: array([False, False, False,  True,  True,  True, False])

In [223]: island_info(keep_longest_true(a))
Out[223]: [(False, 3), (True, 3), (False, 1)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...