Python - 多个列表的成对交集,然后对所有重复项求和
Python - Pairwise intersection of multiple lists, then sum up all duplicates
a = [1,2,3]
b = [2,3,4]
c = [1,2,4]
d = [1,3,6]
大家好,
我有上面的列表,我想按以下格式显示每两个列表的成对 intersection/overlap(重复整数的数量)。任何人都知道如何实现这一目标? (任何方法都很好,但很好奇 iterative/loop 是实现此目的的唯一方法吗?)
a b c d
a 3 2 2 2
b 2 3 2 1
c 2 2 3 1
d 2 1 1 3
真正的目标对我来说更难,我需要总结每两个列表中的所有重复数字。例如,列表 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
下面是一个对 numpy 数组 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]]
您可以将 4 个列表放入字典中,将它们转换为集合,使用 itertools.combinations_with_replacement
生成 4 个列表中 2 个之间的所有组合,将它们放入由 [=13= 索引的字典中] 键组合的值是值集的交集的长度,并在嵌套循环中打印输出:
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
使用方法 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]])
a = [1,2,3]
b = [2,3,4]
c = [1,2,4]
d = [1,3,6]
大家好,
我有上面的列表,我想按以下格式显示每两个列表的成对 intersection/overlap(重复整数的数量)。任何人都知道如何实现这一目标? (任何方法都很好,但很好奇 iterative/loop 是实现此目的的唯一方法吗?)
a b c d
a 3 2 2 2
b 2 3 2 1
c 2 2 3 1
d 2 1 1 3
真正的目标对我来说更难,我需要总结每两个列表中的所有重复数字。例如,列表 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
下面是一个对 numpy 数组 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]]
您可以将 4 个列表放入字典中,将它们转换为集合,使用 itertools.combinations_with_replacement
生成 4 个列表中 2 个之间的所有组合,将它们放入由 [=13= 索引的字典中] 键组合的值是值集的交集的长度,并在嵌套循环中打印输出:
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
使用方法 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]])