Python脚本需求:按CSV中列1='1'的行分组聚合列1-4并求和列5
解决方案:按分组头拆分数据后再聚合
要解决全局聚合的问题,核心是先把CSV数据按列1='1'的行拆分成独立分组,每个分组包含一个头行和后续所有到下一个头行之前的列1='2'的行,再在每个分组内完成按列1-4分组、列5求和的操作。
方法一:用Python标准库csv模块处理(无额外依赖)
import csv # 存储最终聚合结果 final_results = [] # 读取输入CSV with open('input.csv', 'r', newline='', encoding='utf-8') as infile: reader = csv.DictReader(infile) # 替换为你实际的列名,比如col1/col2/col3/col4/col5 current_group_head = None group_agg_data = {} for row in reader: if row['col1'] == '1': # 遇到新分组头,先处理上一个分组的聚合数据 if current_group_head is not None: for key, total in group_agg_data.items(): final_results.append({ '分组头_col1': current_group_head['col1'], '分组头_col2': current_group_head['col2'], # 按需添加分组头的其他字段 '聚合_col1': key[0], '聚合_col2': key[1], '聚合_col3': key[2], '聚合_col4': key[3], 'col5求和': total }) # 重置当前分组的头和聚合数据 current_group_head = row group_agg_data = {} elif row['col1'] == '2': # 构建分组键:(col1, col2, col3, col4) agg_key = (row['col1'], row['col2'], row['col3'], row['col4']) # 转换col5为数值类型,避免字符串拼接 col5_value = float(row['col5']) if '.' in row['col5'] else int(row['col5']) # 累加求和 if agg_key in group_agg_data: group_agg_data[agg_key] += col5_value else: group_agg_data[agg_key] = col5_value # 处理最后一个分组的数据 if current_group_head is not None and group_agg_data: for key, total in group_agg_data.items(): final_results.append({ '分组头_col1': current_group_head['col1'], '分组头_col2': current_group_head['col2'], '聚合_col1': key[0], '聚合_col2': key[1], '聚合_col3': key[2], '聚合_col4': key[3], 'col5求和': total }) # 写入输出CSV with open('output.csv', 'w', newline='', encoding='utf-8') as outfile: fieldnames = ['分组头_col1', '分组头_col2', '聚合_col1', '聚合_col2', '聚合_col3', '聚合_col4', 'col5求和'] writer = csv.DictWriter(outfile, fieldnames=fieldnames) writer.writeheader() writer.writerows(final_results)
关键说明:
- 逐行遍历CSV时,用
current_group_head记录当前分组的头行,遇到新头行就先处理完上一个分组的聚合数据。 - 对每个分组内的
列1='2'的行,用(col1, col2, col3, col4)作为唯一键,累加列5的数值。 - 注意将列5的字符串转为数值类型,否则会出现字符串拼接错误。
方法二:用Pandas处理(简洁高效,适合大数据量)
import pandas as pd # 读取CSV文件 df = pd.read_csv('input.csv') # 生成分组ID:每个`列1='1'`的行及后续行分配同一个ID,实现分组拆分 df['group_id'] = (df['col1'] == '1').cumsum() # 筛选列1='2'的行,按group_id+col1-col4分组,对col5求和 aggregated_df = df[df['col1'] == '2'].groupby(['group_id', 'col1', 'col2', 'col3', 'col4'])['col5'].sum().reset_index() # 可选:关联分组头的其他字段(比如分组头的col2/col3) group_headers = df[df['col1'] == '1'][['group_id', 'col2', 'col3']] final_df = pd.merge(aggregated_df, group_headers, on='group_id', how='left', suffixes=('', '_分组头')) # 写入结果 final_df.to_csv('output_pandas.csv', index=False, encoding='utf-8')
关键说明:
(df['col1'] == '1').cumsum()会生成递增的分组ID,自动把每个头行和后续行归为同一组。- 分组求和时带上
group_id,确保每个分组内的聚合独立,不会全局合并。 - 如果不需要保留分组头信息,可以直接输出
aggregated_df。
内容的提问来源于stack exchange,提问作者user46587
相关产品推荐
相关产品推荐

