我正在尝试根据条件计算各种项目的出现次数。到目前为止我所拥有的这个函数给出了两个项目会增加计数器:
给定[('a', 'a'), ('a', 'b'), ('b', 'a')]
将output defaultdict(<class 'collections.Counter'>, {'a': Counter({'a': 1, 'b': 1}), 'b': Counter({'a': 1})
该功能可以在下面看到
def freq(samples=None):
out = defaultdict(Counter)
if samples:
for (c, s) in samples:
out[c][s] += 1
return out
虽然仅限于使用元组,但我希望它更通用并且可以处理任意数量的变量,例如,[('a', 'a', 'b'), ('a', 'b', 'c'), ('b', 'a', 'a')]
仍然有效,我可以查询结果让我们说res['a']['b']
并获取'c'
的计数。
在Python中执行此操作的最佳方法是什么?
答案 0 :(得分:2)
假设列表中的所有元组具有相同的长度:
from collections import Counter
from itertools import groupby
from operator import itemgetter
def freq(samples=[]):
sorted_samples = sorted(samples)
if sorted_samples and len(sorted_samples[0]) > 2:
return {key: freq(value[1:] for value in values) for key, values in groupby(sorted_samples, itemgetter(0))}
else:
return {key: Counter(value[1] for value in values) for key, values in groupby(sorted_samples, itemgetter(0))}
这给出了:
freq([('a', 'a'), ('a', 'b'), ('b', 'a'), ('a', 'c')])
>>> {'a': Counter({'a': 1, 'b': 1, 'c': 1}), 'b': Counter({'a': 1})}
freq([('a', 'a', 'a'), ('a', 'b', 'c'), ('b', 'a', 'a'), ('a', 'c', 'c')])
>>> {'a': {'a': Counter({'a': 1}), 'b': Counter({'c': 1}), 'c': Counter({'c': 1})}, 'b': {'a': Counter({'a': 1})}}
答案 1 :(得分:0)
一种选择是使用完整的元组作为键
def freq(samples=[]):
out = Counter()
for sample in samples:
out[sample] += 1
return out
然后将事物作为
返回Counter({('a', 'a', 'b'): 1, ('a', 'b', 'c'): 1, ('b', 'a', 'a'): 1})
您可以将元组转换为字符串以选择某些切片,例如"('a', 'b',"
。例如,在新词典{k: v for k,v in out.items() if str(k)[:10] == "('a', 'b',"}
中。
如果这些组的长度确实是2或3,但两者都不是,则可以更改为:
def freq(samples):
l = len(samples[0])
if l == 2:
out = defaultdict(lambda: 0)
for a, b in samples:
out[a][b] += 1
elif l == 3:
out = defaultdict(lambda: defaultdict(lambda: 0))
for a, b, c in samples:
out[a][b][c] += 1
return out