【问题标题】:Find frequency of subsets amongst multiple sets在多个集合中查找子集的频率
【发布时间】:2019-10-16 16:31:14
【问题描述】:

我的技能列表如下:

skills = ['Listening', 'Written_Expression','Clerical',
         'Night_Vision', 'Accounting']

我有一个单独的集合列表,每个集合都包含与特定工作相关的技能:

job_skills =  
     [{'Listening','Written_Expression','Clerical','Night_Vision'},
     {'Chemistry','Written_Expression','Clerical','Listening'},
     .
     .
     ]

我想计算 2 个独特技能的每个组合是 job_skills 中集合的子集的频率,并返回列表/集合列表,其组合和频率如下:

skill_pairs = [{'Listening', 'Written_Expression', 2},
              {'Listening', 'Clerical', 2},
              .
              .
              {'Night_Vision', 'Accounting', 0}]

目前我正在做以下事情:

skill_combos = []
for idx, i in enumerate(skills):
    for jdx, j in enumerate(skills[idx+1:]):
        temp = []
        for job in range(len(job_skills)):
            temp.append(set([i,j]).issubset(job_skills[job])
        skill_combos.append([i,j,sum(temp)])

这可以完成工作,但考虑到我有大约 50 万个技能组合,它的速度很慢。有没有更快的方法来做到这一点?理想情况下不使用 3 个循环。

谢谢

【问题讨论】:

  • 这可能是 codereview.stackexchange.com 的一个很好的候选者

标签: python set subset


【解决方案1】:

你只需要统计出现的组合,其余为零,例如:

from collections import Counter
from itertools import combinations

job_skills = [{'Listening', 'Written_Expression', 'Clerical', 'Night_Vision'},
              {'Chemistry', 'Written_Expression', 'Clerical', 'Listening'}]


counts = Counter(combo for skill_set in job_skills for combo in combinations(skill_set, 2))

for key, value in counts.items():
    print(key, value)

输出

('Clerical', 'Written_Expression') 2
('Clerical', 'Listening') 2
('Clerical', 'Night_Vision') 1
('Written_Expression', 'Listening') 2
('Written_Expression', 'Night_Vision') 1
('Listening', 'Night_Vision') 1
('Clerical', 'Chemistry') 1
('Written_Expression', 'Chemistry') 1
('Listening', 'Chemistry') 1

itertools.combinationscollections.Counter。如果您想要一个为缺少的字典返回 0 的字典,请将 counts 包装为 defaultdict

total = defaultdict(int)
total.update(counts)
print(total[('Night_Vision', 'Accounting')])

输出

0

【讨论】:

    【解决方案2】:

    不确定它是否更快,但您可以使用计数器的组合。我的解决方案只计算一次组合。然后它使用issubset 表示法。

    from itertools import combinations
    from collections import Counter
    
    skills = ['Listening', 'Written_Expression','Clerical',
             'Night_Vision', 'Accounting']
    job_skills = [{'Listening','Written_Expression','Clerical','Night_Vision'}, {'Chemistry','Written_Expression','Clerical','Listening'}]
    
    pairs = {frozenset(x) for x in combinations(skills, 2)}
    c = Counter(pair for pair in pairs for job in job_skills if pair.issubset(job))
    
    for pair in pairs: # Adding the pairs that had no matches
        if pair not in c:
            c[pair] = 0
    
    for key, count in c.items():
        print(key, count)
    

    输出:

    frozenset({'Written_Expression', 'Clerical'}) 2
    frozenset({'Listening', 'Clerical'}) 2
    frozenset({'Written_Expression', 'Listening'}) 2
    frozenset({'Written_Expression', 'Night_Vision'}) 1
    frozenset({'Listening', 'Night_Vision'}) 1
    frozenset({'Clerical', 'Night_Vision'}) 1
    frozenset({'Written_Expression', 'Accounting'}) 0
    frozenset({'Clerical', 'Accounting'}) 0
    frozenset({'Listening', 'Accounting'}) 0
    frozenset({'Night_Vision', 'Accounting'}) 0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-30
      相关资源
      最近更新 更多