如何让Collections.Counter统计含空值的属性并显示0计数?
问题:统计节点属性时包含空值属性并计数为0
我写了一段代码用来分析node.properties这个JSON字典:
from collections import defaultdict, Counter def summarise_all_model_properties( all_nodes: list ) -> defaultdict[str, Counter[str]]: propdicts = defaultdict(Counter) for node in all_nodes: propdicts[node.model_type].update( k for k in node.properties.keys() if node.properties[k] ) return propdicts
这段代码能正确统计node.properties[propertyName]非空/非假值的次数,按node.model_type分组返回非空属性及其计数。但我希望把存在但值为空的属性也纳入Counter并显示计数为0。
举个例子:
# 示例节点 foo.properties = {"a": "something!", "b": '', "c": 123} bar.properties = {"a": "", "b": '', "c": "something else!"} all_nodes = [foo,bar]
当前代码返回的结果是:
Counter({"a": 1, "c": 2})
但我期望得到:
Counter({"a": 1, "b":0, "c": 2})
补充说明:后续要把属性及非空使用次数输出到CSV表格,而且无法提前知晓所有属性名(属性来自JSON文件),对应的CSV输出代码如下:
for model_type, counter in summarise_all_model_properties(all_nodes).items(): for propname, count in counter.items(): csv.writerow(model_type, propname, count)
解决方案
要实现这个需求,需要先收集所有出现过的属性名,再给每个分组的Counter补充这些属性(空值的设为0)。修改后的代码如下:
from collections import defaultdict, Counter def summarise_all_model_properties( all_nodes: list ) -> defaultdict[str, Counter[str]]: # 收集所有出现过的属性名 all_properties = set() for node in all_nodes: all_properties.update(node.properties.keys()) # 统计非空属性的出现次数 propdicts = defaultdict(Counter) for node in all_nodes: model_type = node.model_type for prop, value in node.properties.items(): if value: propdicts[model_type][prop] += 1 # 给每个分组补充所有属性,未出现的设为0 for model_type in propdicts: for prop in all_properties: if prop not in propdicts[model_type]: propdicts[model_type][prop] = 0 return propdicts
代码说明
- 收集全量属性名:遍历所有节点,将所有
properties的键存入集合,确保不重复覆盖。 - 统计非空属性:逐个遍历节点的属性,仅当属性值非空时增加对应计数。
- 补充空值属性:对每个
model_type的Counter,检查所有收集到的属性,不存在的属性直接设为0,保证所有出现过的属性都会被纳入结果。
修改后,原有CSV输出代码就能将所有属性(包括空值属性)都写入表格,完全符合需求。
内容的提问来源于stack exchange,提问作者Greedo
相关产品推荐
相关产品推荐

