计算列表列表中 2 个变量的共同出现
Count co-appearance of 2 variables in list of lists
我有一个列表列表,每个列表都包含字符串值(~130.000 个列表,每个列表有~15 个项目)。列表可能包含重复项,但这是设计使然,它们需要保留 = 我不能在此处使用集合。
我创建了每个列表值的元组组合(~5.600.000 个元组)并想计算每个元组值单独和一起出现在列表中的次数。
所以我需要查找每个元组值在列表中出现的次数。所以 (5.600.000 * (130.000 * 15)) 这是......很多。
示例:
tags: [['a', 'b', 'c', 'aa', 'bb', '2019'], ['a', 'd', '18', 'gb'], ['aa', 'a', 'dd', 'fb', 'la'], ['aa', 'd', 'ddaa', 'b', 'k', 'l']]
tagSet: {('a', 'aa'), ('a', 'b'), ('b', 'd'), ('aa', 'b'), ('aa', 'd'), ('a', 'd')}
for tagTuple in tagSet:
tagA = tagTuple[0]
tagB = tagTuple[1]
sumA = sum(tagA in item for item in tags )
sumB = sum(tagB in item for item in tags )
sumAB = ??
对于元组 (a, b),结果应该是
a: 3, b:2, a+b: 1
但是我如何计算 a 和 b 在每个列表中一起出现的次数?
需要一种高效的方法,因为我需要检查大量的列表和元组。
只需使用与 if
语句中相同的检测表达式:
sumAB = sum(tagA in item and tagB in item for item in tags )
只需使用和条件tagA in item and tagB in item
:
tags = [['a', 'b', 'c', 'aa', 'bb', '2019'], ['a', 'd', '18', 'gb'], ['aa', 'a', 'dd', 'fb', 'la'], ['aa', 'd', 'ddaa', 'b', 'k', 'l']]
#tagSet = {('a', 'aa'), ('a', 'b'), ('b', 'd'), ('aa', 'b'), ('aa', 'd'), ('a', 'd')}
tagSet = [('a', 'b')]
for tagTuple in tagSet:
tagA = tagTuple[0]
tagB = tagTuple[1]
sumA = sum(tagA in item for item in tags )
sumB = sum(tagB in item for item in tags )
sumAB = sum(tagA in item and tagB in item for item in tags)
print(sumA)
print(sumB)
print(sumAB)
为 tags
列表中的每个元素出现的频率创建一个 collections.Counter
,并为 Counter
每个元素一起出现的频率创建一个 dict
彼此元素。
from collections import Counter, defaultdict
from itertools import combinations
counts = Counter()
co_counts = defaultdict(Counter)
for lst in tags:
c = Counter(lst)
counts.update(c)
for a, b in combinations(set(lst), 2):
co_counts[a][b] += min(c[a], c[b])
co_counts[b][a] += min(c[a], c[b])
创建这些也不完全便宜,但比您目前正在做的要便宜得多。如果您的 tags
和 tagSet
分别有 N
和 M
元素,并且 tags
中的列表平均有 K
个元素(K
比 N
或 M
) 小得多,那么它有 "only" N * K²
而不是 N * M * K
.
然后,您可以直接从那些 Counter
词典中获取您的值。
for a, b in tagSet:
print(a, b, counts[a], counts[b], co_counts[a][b])
这给出了以下输出:
a b 3 2 1
a aa 3 3 2
b d 2 2 1
a d 3 2 1
aa d 3 2 1
aa b 3 2 2
我有一个列表列表,每个列表都包含字符串值(~130.000 个列表,每个列表有~15 个项目)。列表可能包含重复项,但这是设计使然,它们需要保留 = 我不能在此处使用集合。
我创建了每个列表值的元组组合(~5.600.000 个元组)并想计算每个元组值单独和一起出现在列表中的次数。
所以我需要查找每个元组值在列表中出现的次数。所以 (5.600.000 * (130.000 * 15)) 这是......很多。
示例:
tags: [['a', 'b', 'c', 'aa', 'bb', '2019'], ['a', 'd', '18', 'gb'], ['aa', 'a', 'dd', 'fb', 'la'], ['aa', 'd', 'ddaa', 'b', 'k', 'l']]
tagSet: {('a', 'aa'), ('a', 'b'), ('b', 'd'), ('aa', 'b'), ('aa', 'd'), ('a', 'd')}
for tagTuple in tagSet:
tagA = tagTuple[0]
tagB = tagTuple[1]
sumA = sum(tagA in item for item in tags )
sumB = sum(tagB in item for item in tags )
sumAB = ??
对于元组 (a, b),结果应该是
a: 3, b:2, a+b: 1
但是我如何计算 a 和 b 在每个列表中一起出现的次数?
需要一种高效的方法,因为我需要检查大量的列表和元组。
只需使用与 if
语句中相同的检测表达式:
sumAB = sum(tagA in item and tagB in item for item in tags )
只需使用和条件tagA in item and tagB in item
:
tags = [['a', 'b', 'c', 'aa', 'bb', '2019'], ['a', 'd', '18', 'gb'], ['aa', 'a', 'dd', 'fb', 'la'], ['aa', 'd', 'ddaa', 'b', 'k', 'l']]
#tagSet = {('a', 'aa'), ('a', 'b'), ('b', 'd'), ('aa', 'b'), ('aa', 'd'), ('a', 'd')}
tagSet = [('a', 'b')]
for tagTuple in tagSet:
tagA = tagTuple[0]
tagB = tagTuple[1]
sumA = sum(tagA in item for item in tags )
sumB = sum(tagB in item for item in tags )
sumAB = sum(tagA in item and tagB in item for item in tags)
print(sumA)
print(sumB)
print(sumAB)
为 tags
列表中的每个元素出现的频率创建一个 collections.Counter
,并为 Counter
每个元素一起出现的频率创建一个 dict
彼此元素。
from collections import Counter, defaultdict
from itertools import combinations
counts = Counter()
co_counts = defaultdict(Counter)
for lst in tags:
c = Counter(lst)
counts.update(c)
for a, b in combinations(set(lst), 2):
co_counts[a][b] += min(c[a], c[b])
co_counts[b][a] += min(c[a], c[b])
创建这些也不完全便宜,但比您目前正在做的要便宜得多。如果您的 tags
和 tagSet
分别有 N
和 M
元素,并且 tags
中的列表平均有 K
个元素(K
比 N
或 M
) 小得多,那么它有 "only" N * K²
而不是 N * M * K
.
然后,您可以直接从那些 Counter
词典中获取您的值。
for a, b in tagSet:
print(a, b, counts[a], counts[b], co_counts[a][b])
这给出了以下输出:
a b 3 2 1
a aa 3 3 2
b d 2 2 1
a d 3 2 1
aa d 3 2 1
aa b 3 2 2