Разделение массива np кортежей по последнему значению, но только если совпадает остальная часть кортежа - PullRequest
0 голосов
/ 14 марта 2020

У меня ОЧЕНЬ длинный numpy массив 3d-кортежей:

array([('Session A', 'mov1', 1932), ('Session A', 'mov1', 1934),
       ('Session A', 'mov1', 1936), ..., ('Session B', 'mov99', 5306),
       ('Session B', 'mov99', 5308), ('Session B', 'mov99', 5310)], dtype=object)

Первое и второе значения каждого кортежа взяты из небольшого набора:

first_values = set('Session A', 'Session B')
second_values = set('mov1', 'mov2', 'mov3', ... , 'mov100')

Но третий значение может быть любым положительным целым числом.
Я ищу хороший Pythoni c способ разделения исходного массива на отдельные массивы кортежей, где:

  1. Все кортежи имеют одинаковое значение для 1-й и 2-й аргументы.
  2. Разница между 3-м аргументом каждого последовательного кортежа не превышает заданного значения delta

Так, например:

delta = 5
data = [('Session A', 'mov1', 1000), ('Session A', 'mov1', 1001), ('Session A', 'mov1', 1003), ('Session A', 'mov1', 1007), ('Session A', 'mov1', 1010), ('Session A', 'mov1', 1050), ('Session A', 'mov1', 1052), ('Session A', 'mov2', 1002), ('Session A', 'mov2', 1004)]

*magical python function*

result = [
    [('Session A', 'mov1', 1000), ('Session A', 'mov1', 1001), ('Session A', 'mov1', 1003), ('Session A', 
    'mov1', 1007), ('Session A', 'mov1', 1010)], 
    [('Session A', 'mov1', 1050), ('Session A', 'mov1', 1052)],
    [('Session A', 'mov2', 1002), ('Session A', 'mov2', 1004)]
]

Я нашел этот ответ но это не совсем то, что мне нужно. Есть предложения?

1 Ответ

3 голосов
/ 14 марта 2020

Вы можете достичь желаемого, используя itertools, чтобы сгруппировать данные по первым двум элементам каждого кортежа, а затем выполнить цикл по этим результатам, чтобы разбить списки, когда изменение значения третьего элемента превышает дельту. Это может быть реализовано следующим образом:

import itertools

delta = 5
data = [
    ('Session A', 'mov1', 1000), ('Session A', 'mov1', 1001),
    ('Session A', 'mov1', 1003), ('Session A', 'mov1', 1007),
    ('Session A', 'mov1', 1010), ('Session A', 'mov1', 1050),
    ('Session A', 'mov1', 1052), ('Session A', 'mov2', 1002),
    ('Session A', 'mov2', 1004)
]

result = []
for key, group in itertools.groupby(data, key = lambda x: (x[0],x[1])):
    work = []
    prev = None
    for elem in list(group):
        if (prev is not None) and (elem[2] - prev > delta):
            result.append(work)
            work = []
        work.append(elem)
        prev = elem[2]
    result.append(work)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...