计算列表列表中 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])

创建这些也不完全便宜,但比您目前正在做的要便宜得多。如果您的 tagstagSet 分别有 NM 元素,并且 tags 中的列表平均有 K 个元素(KNM) 小得多,那么它有 "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