基于多条件聚合CSV行:用列表字典模拟数据透视表分组求和
手动用列表+字典实现数据透视表分组汇总
嘿,我完全懂你想要的——不用Pandas,纯靠基础的列表和字典手动实现类似Excel透视表的分组汇总,这确实是个练手的好机会!我来给你拆解下核心思路和具体实现步骤:
核心思路
我们可以用嵌套字典来存储分组后的累计数据:
- 外层字典的键用
(成本中心, 月份)这样的元组(因为元组是可哈希类型,能作为字典的键,完美对应唯一的分组组合) - 内层字典用来存两类金额的累计值,比如
{'金额1': 累计值, '金额2': 累计值}
遍历CSV的每一行时,我们只需要找到对应的分组键,然后把当前行的金额累加到对应的值里就行,一次遍历就能完成所有计算,效率很高。
具体代码实现
第一步:模拟CSV数据(或读取真实文件)
假设你已经把CSV解析成了列表形式(如果是真实文件,用csv模块读取即可,后面会补充示例):
# 模拟解析后的CSV数据,每行是一个字典(也可以是列表,后面会调整) csv_data = [ {'成本中心': 'A', '月份': '2024-01', '金额1': 100, '金额2': 50}, {'成本中心': 'A', '月份': '2024-01', '金额1': 200, '金额2': 80}, {'成本中心': 'B', '月份': '2024-01', '金额1': 150, '金额2': 30}, {'成本中心': 'A', '月份': '2024-02', '金额1': 180, '金额2': 60}, {'成本中心': 'B', '月份': '2024-02', '金额1': 220, '金额2': 70}, ]
第二步:分组汇总逻辑
# 初始化空的汇总字典 summary_dict = {} # 遍历每一行数据 for row in csv_data: # 提取当前行的关键字段 cost_center = row['成本中心'] month = row['月份'] amount1 = row['金额1'] amount2 = row['金额2'] # 生成唯一的分组键(成本中心+月份的组合) group_key = (cost_center, month) # 如果这个分组还没在汇总字典里,初始化累计值 if group_key not in summary_dict: summary_dict[group_key] = {'金额1': 0, '金额2': 0} # 把当前行的金额累加到对应分组的累计值里 summary_dict[group_key]['金额1'] += amount1 summary_dict[group_key]['金额2'] += amount2
第三步:转换成你需要的输出格式
遍历完成后,把嵌套字典转换成更易读的列表格式(比如每个元素是一个包含分组和汇总值的字典):
# 转换为目标输出格式 final_result = [] for (cost_center, month), total_amounts in summary_dict.items(): final_result.append({ '成本中心': cost_center, '月份': month, '汇总金额1': total_amounts['金额1'], '汇总金额2': total_amounts['金额2'] }) # 打印结果看看 for item in final_result: print(item)
运行后你会得到这样的输出:
{'成本中心': 'A', '月份': '2024-01', '汇总金额1': 300, '汇总金额2': 130} {'成本中心': 'B', '月份': '2024-01', '汇总金额1': 150, '汇总金额2': 30} {'成本中心': 'A', '月份': '2024-02', '汇总金额1': 180, '汇总金额2': 60} {'成本中心': 'B', '月份': '2024-02', '汇总金额1': 220, '汇总金额2': 70}
处理真实大CSV文件的版本
如果你的文件是真实的大CSV,用Python内置的csv模块读取即可,只需要调整字段提取的方式:
import csv summary_dict = {} with open('your_large_file.csv', 'r', encoding='utf-8') as f: reader = csv.reader(f) # 先读取表头,找到各字段的索引 header = next(reader) cc_idx = header.index('成本中心') month_idx = header.index('月份') amt1_idx = header.index('金额1') amt2_idx = header.index('金额2') # 逐行读取并处理 for row in reader: cost_center = row[cc_idx] month = row[month_idx] # 注意把字符串转成数值类型(根据你的数据可能是int或float) amount1 = float(row[amt1_idx]) amount2 = float(row[amt2_idx]) group_key = (cost_center, month) if group_key not in summary_dict: summary_dict[group_key] = {'金额1': 0.0, '金额2': 0.0} summary_dict[group_key]['金额1'] += amount1 summary_dict[group_key]['金额2'] += amount2 # 同样转换为目标格式 final_result = [] for (cc, month), amts in summary_dict.items(): final_result.append({ '成本中心': cc, '月份': month, '汇总金额1': amts['金额1'], '汇总金额2': amts['金额2'] })
额外优化:排序结果
如果需要按成本中心和月份排序结果,用sorted()函数就行:
# 按成本中心升序,再按月份升序排序 sorted_result = sorted(final_result, key=lambda x: (x['成本中心'], x['月份']))
这个思路的好处是逻辑清晰,完全基于基础数据结构,而且时间复杂度是O(n)(n是行数),处理大文件也不会有性能问题。
内容的提问来源于stack exchange,提问作者barciewicz
相关产品推荐
相关产品推荐

