Python - попарное пересечение нескольких списков, затем суммировать все дубликаты - PullRequest
0 голосов
/ 19 сентября 2018
a = [1,2,3]
b = [2,3,4]
c = [1,2,4]
d = [1,3,6]

Привет всем,

У меня есть списки, приведенные выше, я хотел бы показать попарно пересечение / перекрытие (число дублированных целых чисел) каждого из двух списков, как в следующем формате.Кто-нибудь знает, как этого добиться?(любой метод был бы хорош, но просто любопытно, является ли итеративный / цикличный цикл единственным методом, позволяющим достичь этого?)два списка.Например, список a и список b дублируются под номерами 2 и 3, поэтому мне нужно 5 здесь.Конечная цель как ниже:

   a  b  c  d
a  6  5  3  4
b  5  9  6  3
c  3  6  7  1
d  4  3  1  10

Ответы [ 3 ]

0 голосов
/ 19 сентября 2018

Вы можете поместить 4 списка в dict, преобразовать их в наборы, использовать itertools.combinations_with_replacement, чтобы получить все комбинации между 2 4 списками, поместить их в dict, проиндексированный frozenset комбинации клавиш сзначения, представляющие собой длину пересечения наборов значений, и распечатки выходных данных во вложенном цикле:

from itertools import combinations_with_replacement
d = {'a': [1,2,3], 'b': [2,3,4], 'c': [1,2,4], 'd': [1,3,6]}
s = {frozenset([a[0], b[0]]): len(a[1] & b[1]) for a, b in combinations_with_replacement([(k, set(v)) for k, v in d.items()], 2)}
print(' ', ' '.join(d))
for i in d:
    print(i, end=' ')
    for j in d:
        print(s[frozenset([i, j])], end=' ')
    print()

Это выводит:

  a b c d
a 3 2 2 2 
b 2 3 2 1 
c 2 2 3 1 
d 2 1 1 3 
0 голосов
/ 19 сентября 2018

Используя метод np.in1d:

import numpy as np
R = []
A = np.array([a,b,c,d])
for x in A:
    A = np.array([a,b,c,d])
    ind = np.in1d(A,x).reshape(np.size(A,0),np.size(A,1))
    A[~ind] = 0
    R.append(A.sum(1))

R = np.vstack(R)

С R:

array([[ 6,  5,  3,  4],
       [ 5,  9,  6,  3],
       [ 3,  6,  7,  1],
       [ 4,  3,  1, 10]])
0 голосов
/ 19 сентября 2018

Ниже приведена реализация, которая выполняет попарную операцию на массиве массивов X. Этот подход предполагает, что операция симметрична для повышения скорости.

from itertools import combinations_with_replacement
import numpy as np

def pairwise(X, operation):        
    # Initialise precomputed matrix
    precomputed = np.zeros((X.shape[0], X.shape[0]), dtype='int')
    # Initialise iterator over objects in X
    iterator    = combinations_with_replacement(range(X.shape[0]), 2)
    # Perform the operation on each pair
    for i, j in iterator:
        precomputed[i, j] = operation(X[i], X[j])           
    # Make symmetric and return
    return precomputed + precomputed.T - np.diag(np.diag(precomputed))

Мы можем определить функцию, чтобы показать степень перекрытия вдва набора и поместите его в попарную функцию

def overlap(x, y):
    return len(set(x) & set(y))

Обратите внимание, что для этого решения требуется массив numpy, поэтому для вашего примера нам нужно изменить данные перед вводом их в функцию

X = np.array([a, b, c, d])
print(pairwise(X, overlap))

Это дает результат

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