Индексы дубликатов списков во вложенном списке - PullRequest
3 голосов
/ 22 января 2020

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

y = [[1,2,3],[1,2,3],[3,4,5],[6,5,4],[4,2,5],[4,2,5],[1,2,8],[1,2,3]]

, извлеките индексы уникальных списков во вложенный список снова.

Например, выход для указанного выше вложенного списка должен быть

[[0,1,7],[2],[3],[4,5],[6]].

Это потому, что список [1,2,3] присутствует в индексных позициях 0,1,7th, [3,4,5] во 2-й индексной позиции и так далее.

Поскольку я буду иметь дело с большими списками, какой может быть самый оптимальный способ достижения этого в Python?

Ответы [ 4 ]

7 голосов
/ 22 января 2020

Вы можете создать словарь (или OrderedDict, если на старых питонах). Ключи dict будут кортежами подсписков, а значения будут массивом индексов. После циклического просмотра значения словаря будут содержать ваш ответ:

from collections import OrderedDict

y = [[1,2,3],[1,2,3],[3,4,5],[6,5,4],[4,2,5],[4,2,5],[1,2,8],[1,2,3]]

lookup = OrderedDict()
for idx,l in enumerate(y):
    lookup.setdefault(tuple(l), []).append(idx)

list(lookup.values())
# [[0, 1, 7], [2], [3], [4, 5], [6]]
3 голосов
/ 22 января 2020

Вы можете использовать понимание списка и диапазон, чтобы проверить наличие дублирующих индексов и добавить их к result.

result = []
for num in range(len(y)):
    occurances = [i for i, x in enumerate(y) if x == y[num]]
    if occurances not in result: result.append(occurances)

result
#[[0, 1, 7], [2], [3], [4, 5], [6]]
2 голосов
/ 22 января 2020

Еще одно решение:

y = [[1, 2, 3], [1, 2, 3], [3, 4, 5], [6, 5, 4], [4, 2, 5], [4, 2, 5], [1, 2, 8], [1, 2, 3]]

occurrences = {}

for i, v in enumerate(y):
    v = tuple(v)
    if v not in occurrences:
        occurrences.update({v: []})
    occurrences[v].append(i)

print(occurrences.values())
2 голосов
/ 22 января 2020

Рассмотрим numpy, чтобы решить эту проблему:

import numpy as np

y = [
    [1, 2, 3],
    [1, 2, 3],
    [3, 4, 5],
    [6, 5, 4],
    [4, 2, 5],
    [4, 2, 5],
    [1, 2, 8],
    [1, 2, 3]
]

# Returns unique values of array, indices of that
# array, and the indices that would rebuild the original array
unique, indices, inverse = np.unique(y, axis=0, return_index=True, return_inverse=True)

Вот распечатка каждой переменной:

unique = [
[1 2 3]
[1 2 8]
[3 4 5]
[4 2 5]
[6 5 4]]

indices = [0 6 2 4 3]

inverse = [0 0 2 4 3 3 1 0]

Если мы посмотрим на наша переменная - обратная , мы можем видеть, что мы действительно получаем [0, 1, 7] в качестве позиций индекса для нашего первого уникального элемента [1,2,3], все Теперь нам нужно сгруппировать их соответствующим образом.

new_list = []
for i in np.argsort(indices):
    new_list.append(np.where(inverse == i)[0].tolist()) 

Вывод:

new_list = [[0, 1, 7], [2], [3], [4, 5], [6]]

Наконец, ссылки на приведенный выше код:

Numpy - уникальный , где , argsort

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...