如何在CSV数据中按Alphabet分组统计Value的频次及占比?
需求与解决方案
需求说明
- 原始CSV包含
Alphabet、Sub alphabet、Value三列,数据示例:A,B,1 A,C,1 A,E,2 A,F,3 D,B,1 D,C,2 D,E,2 D,F,3 - 需要生成新的CSV,包含
Alphabet、Value、Frequency、%四列,规则如下:Frequency为同一Alphabet分组下,相同Value的出现次数%为该Value的频次除以对应Alphabet分组的总频次,格式为百分比(如50%)
- 期望输出示例:
A,1,2,50% A,2,1,25% A,3,1,25% D,1,1,25% D,2,2,50% D,3,1,25%
实现代码
import csv from collections import defaultdict # 统计核心数据:各字母分组下的Value频次,以及分组总数据量 value_freq_map = defaultdict(lambda: defaultdict(int)) group_total_map = defaultdict(int) with open("/Users/name/Desktop/path/alphabetical_list.csv") as in_file: reader = csv.reader(in_file) for row in reader: alphabet = row[0] value = row[2] value_freq_map[alphabet][value] += 1 group_total_map[alphabet] += 1 # 生成结果并写入新CSV with open("/Users/name/Desktop/path/output_result.csv", "w", newline="") as out_file: writer = csv.writer(out_file) # 可选:写入表头,不需要的话注释掉下面一行 # writer.writerow(["Alphabet", "Value", "Frequency", "%"]) # 按字母分组排序输出,Value也按数值排序 for alphabet in sorted(value_freq_map.keys()): total = group_total_map[alphabet] # 按Value的数值大小排序,若Value是字符串类型可去掉key=int for value in sorted(value_freq_map[alphabet].keys(), key=int): freq = value_freq_map[alphabet][value] percentage = f"{round((freq / total) * 100)}%" writer.writerow([alphabet, value, freq, percentage])
代码说明
- 用
collections.defaultdict简化字典结构,避免手动判断键是否存在,提升统计效率 - 第一遍读取原始CSV,完成两个统计:各字母分组下每个Value的出现次数、每个字母分组的总数据量
- 第二遍遍历统计结果,计算百分比并写入新文件,同时通过排序保证输出顺序的规范性
内容的提问来源于stack exchange,提问作者My Car
相关产品推荐
相关产品推荐

