Python 读取汇总信息,作为读取所有原始数据的替代方法,可以只考虑处理汇总计数。我们希望创建一个类似于之前示例的Counter
对象,它会以轮换班和缺陷代码作为键,以缺陷计数作为值。对于给定的汇总信息,只需从输入字典中创建一个Counter
对象。
负责读取汇总数据的函数如下:
from typing import TextIO
from collections import Counter
import csv
def defect_counts(source: TextIO) -> Counter:
rdr = csv.DictReader(source)
assert set(rdr.fieldnames) == set(
["defect_type", "serial_number", "shift"])
rows_ns = (SimpleNamespace(**row) for row in rdr)
convert = map(
lambda d: ((d.shift, d.defect_code), int(d.count)),
rows_ns)
return Counter(dict(convert))
需要一个打开的文件作为输入。首先创建一个csv.DictReader()
函数,来解析从数据库中获得的原始CSV数据。其中包含了一条assert
语句来保证文件包含了预期的数据。
该变体使用匿名对象为每行创建一个二元组。这些二元组具有从轮换和缺陷代码构建而来的复合键,以及整型转换后的计数。生成的结果是一个类似于((shift,defect), count), ((shift,defect), count), ...)
的序列。当把lambda
映射到row_ns
生成器后,会得到一个能生成二元组序列的生成器函数。
然后从二元组集合创建一个字典,并使用这个字典构建一个Counter
对象。这个Counter
对象易于和其他Counter
对象组合在一起,这让我们可以结合从多个数据源获取的汇总详情。该示例中只有一个数据源。
可以将这个单一源赋给defects
变量,其值如下所示:
Counter({('3', 'C'): 49, ('1', 'C'): 45, ('2', 'C'): 34,
('3', 'A'): 33, ('2', 'B'): 31, ('2', 'A'): 26,
('1', 'B'): 21, ('3', 'D'): 20, ('3', 'B'): 17,
('1', 'A'): 15, ('1', 'D'): 13, ('2', 'D'): 5})
这与此前显示的详情汇总相符。不同的是,此时已经汇总了原始数据。这种情况通常出现在从数据库提取了数据并使用SQL进行分组操作的时候。