[英]Finding all segments members of four sets intersections (ala Venn diagram)
我有四組數據:
A=range(10,20)
B=range(5,17)
C=range(15,25)
D=range(18,30)
sets = [A, B, C, D]
我想要做的是獲取相交的內容,可以將其視為此處獲得維恩圖的所有部分(這是完整的情況):
在上面的示例中,分區的填充如下:
() ----> set()
('A',) ----> set()
('B',) ----> {8, 9, 5, 6, 7}
('C',) ----> set()
('D',) ----> {25, 26, 27, 28, 29}
('A', 'B') ----> {10, 11, 12, 13, 14}
('A', 'C') ----> {17}
('A', 'D') ----> set()
('B', 'C') ----> set()
('B', 'D') ----> set()
('C', 'D') ----> {24, 20, 21, 22, 23}
('A', 'B', 'C') ----> {16, 15}
('A', 'B', 'D') ----> set()
('A', 'C', 'D') ----> {18, 19}
('B', 'C', 'D') ----> set()
('A', 'B', 'C', 'D') ----> set()
這些是預期的答案。
我陷入下面的代碼,只能找到所有給定集中必須存在的交集:
# only gives ACD members
test = [tuple([A[0],A[-1]]), tuple([C[0],C[-1]]), tuple([D[0],D[-1]])]
starts, ends = zip(*test)
result = range(max(starts), min(ends) + 1)
# Gives 18,19
怎么做呢? 請注意,我對繪制圖表不感興趣。 我關心的是讓每個細分市場的成員。
我在此處通過博客發布了有關此類問題的解決方案: http : //paddy3118.blogspot.de/2013/07/set-divisionspartitions.html
您可能需要將x..y語法擴展為整數集,但是如果該輸出形式對您有用,那么您可能希望將輸出與此類函數進行接口: http : //rosettacode.org/wiki/Range_extraction
PS那是一個漂亮的維恩圖。
最好使用具有線性運算復雜度(以及輸出的長度)而不是指數的掃描線算法。
A=range(10,20)
B=range(5,17)
C=range(15,25)
D=range(18,30)
sets = [A, B, C, D]
import string
events = []
for letter, set_ in zip(string.ascii_uppercase, sets):
events.append((set_.start, True, letter))
events.append((set_.stop, False, letter))
events.sort()
intersection = set()
intersections = []
last_t = None
for t, insert, letter in events:
if t != last_t and intersection:
intersections.append((''.join(sorted(intersection)), range(last_t, t)))
last_t = t
if insert:
intersection.add(letter)
else:
intersection.remove(letter)
print(intersections)
import itertools
def powerset(iterable):
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
s = list(iterable)
return itertools.chain.from_iterable(itertools.combinations(s, r) for r in range(len(s)+1))
A = set(range(10,20))
B = set(range(5,17))
C = set(range(15,25))
D = set(range(18,30))
titles = (partition for partition in powerset(['A', 'B', 'C', 'D']))
source = (partition for partition in powerset([A, B, C, D]))
for elt in (zip(titles, source)):
try:
res = elt[1][0]
for el in elt[1]:
res.intersection(el)
except IndexError:
pass
print(elt[0], ' = ', res)
輸出=每組之間的交集
() = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}
('A',) = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
('B',) = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
('C',) = {15, 16, 17, 18, 19, 20, 21, 22, 23, 24}
('D',) = {18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}
('A', 'B') = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
('A', 'C') = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
('A', 'D') = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
('B', 'C') = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
('B', 'D') = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
('C', 'D') = {15, 16, 17, 18, 19, 20, 21, 22, 23, 24}
('A', 'B', 'C') = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
('A', 'B', 'D') = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
('A', 'C', 'D') = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
('B', 'C', 'D') = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
('A', 'B', 'C', 'D') = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
它是這樣的:輸出是專門屬於每個分區的一組元素。 它適用於任意數量的集。
import itertools
def intersect(d):
"""
d is an iterable collection of sets or frozensets
returns the intersection of the sets in d"
"""
res = set()
try:
res = set(d[0])
except IndexError:
pass
for elt in d:
elt = set(elt)
res = res.intersection(elt)
return res
A = frozenset(range(10,20))
B = frozenset(range(5,17))
C = frozenset(range(15,25))
D = frozenset(range(18,30))
titles = ('A','B','C','D')
data = (A, B, C, D)
dataset = set(data)
titles_comb, data_comb = [], []
for n in range(len(data)+1):
titles_comb.append(list(itertools.combinations(titles, n)))
data_comb.append(list(itertools.combinations(data, n)))
for title, dat in zip(titles_comb, data_comb):
for t, d in zip(title, dat):
#intersect(d) = elements in the intersection of the sets (what we want, but has overlap)
#complement = sets from data that were not used in intersect(d) (the overlap we want to discard)
result = intersect(d)
complement = dataset.difference(set(d))
comp = set()
for elt in complement:
for e in elt:
comp.add(e)
print(t, "\t---->", result.difference(comp))
輸出=每個分區的內容(不包括所有其他分區)
() ----> set()
('A',) ----> set()
('B',) ----> {8, 9, 5, 6, 7}
('C',) ----> set()
('D',) ----> {25, 26, 27, 28, 29}
('A', 'B') ----> {10, 11, 12, 13, 14}
('A', 'C') ----> {17}
('A', 'D') ----> set()
('B', 'C') ----> set()
('B', 'D') ----> set()
('C', 'D') ----> {24, 20, 21, 22, 23}
('A', 'B', 'C') ----> {16, 15}
('A', 'B', 'D') ----> set()
('A', 'C', 'D') ----> {18, 19}
('B', 'C', 'D') ----> set()
('A', 'B', 'C', 'D') ----> set()
您是否嘗試過使用python 集 ?
A = set(range(10,20))
B = set(range(5,17))
C = set(range(15,25))
D = set(range(18,30))
A.intersection(B).intersection(C)
set([15, 16])
A.intersection(B)
set([10, 11, 12, 13, 14, 15, 16])
A.intersection(C).intersection(D)
set([18, 19])
A.intersection(B).intersection(C).intersection(D)
set()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.