从计数器类型的对象构建直方图

Build histogram from objects of type counter

我使用集合中的计数器来生成一个大的计数器列表,即 List = [Counter({'A': 4}), Counter({'A': 2}), Counter( {'A': 4}, {'B', 3})...].

我想根据该列表构建直方图,其中该直方图的每个 bin 都是一种特定类型的计数器,即计数器计数的每个元素的数量相同。

这是一个例子

from collections import Counter
data = [['A', 'B', 'B'], ['A', 'B', 'B'], ['A', 'B', 'B'], ['C']]
data_counters = []
for d in data:
    data_counters.append(Counter(d))

我可以生成所有可能的计数器结果的列表,然后计算每个计数器在 data_counters 中出现的次数。但这很难,因为所有可能结果的数量都很大。

严格来说这道题只是一个多维直方图的计算,每个维度对应一个字母。但关键是我想避免这种情况,只使用多次出现的字母组合的 bins,而不查看详细信息。

计数器对象不可哈希,因此我们不能对它们再次使用相同的计数器函数。处理这种情况的一种方法是使用 frozenset 而不是 Counter dictionaries。缺点是我们必须将 frozensets 重新翻译成类似字符串的东西,matplotlib 可以将其用于条形图,也就是直方图:

from collections import Counter
from matplotlib import pyplot as plt

data_list = [['A', 'B', 'B'], ['B', 'A', 'B'], ['A', 'A', 'B'], ['C']]
data_counter = Counter(frozenset(Counter(d).items()) for d in data_list)

plt.xticks(rotation=45, ha="right")
plt.bar([str(list(x)) for x in data_counter.keys()], data_counter.values())
plt.tight_layout()

plt.show()

示例输出: