如何用Python Pandas按id分组求和并保留唯一id行及报错修复
问题解决方法
原代码的核心问题
第一个版本求和未生效的原因
df.groupby(['id'])[cols].sum()执行后没有将结果赋值回变量,原df完全未被修改,后续仍使用原数据导出,自然看不到求和效果。sort_index(by=['id'])是旧版pandas语法,新版应使用sort_values(by='id')。
第二个版本KeyError的原因
unique_ids = [range(1,150000)]错误地把range对象包装成了列表,导致传入.loc的是包含单个range的列表,pandas无法识别这种格式的索引,因此报错。
正确实现代码
基础版本(单文件)
import pandas as pd # 生成列名,简化写法 col_names = ['id'] + [f'H{i}' for i in range(1,25)] df = pd.read_csv(i, sep='\t', names=col_names) # 筛选所有H开头的列 h_cols = df.filter(regex='^H').columns # 按id分组求和,重置索引让id回到普通列 df_grouped = df.groupby('id')[h_cols].sum().reset_index() # 按id升序排序 df_final = df_grouped.sort_values(by='id', ascending=True) # 导出结果 df_final.to_csv(outfile, sep='\t', index=False, header=False)
大文件/多文件优化版本
针对数万行的大文件或多文件场景,可通过指定数据类型减少内存占用,同时支持批量处理:
import pandas as pd import glob # 获取所有待处理的tsv文件 input_files = glob.glob('*.tsv') col_names = ['id'] + [f'H{i}' for i in range(1,25)] # 指定列数据类型,降低内存消耗 dtype_spec = {'id': int} for col in col_names[1:]: dtype_spec[col] = int for file in input_files: df = pd.read_csv(file, sep='\t', names=col_names, dtype=dtype_spec) h_cols = df.filter(regex='^H').columns df_grouped = df.groupby('id')[h_cols].sum().reset_index() # 若需强制保留1到150000的所有id(即使原文件无对应行),用reindex补全 df_final = df_grouped.set_index('id').reindex(range(1, 150000)).reset_index() # 缺失id对应的H列填充为0 df_final = df_final.fillna(0) df_final.to_csv(f'processed_{file}', sep='\t', index=False, header=False)
关键说明
reset_index():分组后id会成为索引,该方法将其转回普通列,方便后续导出和排序。reindex(range(1, 150000)):用于强制生成1到150000的完整id序列,原文件中不存在的id对应的H列会填充NaN,可通过fillna(0)转为0。- 大文件处理时指定
dtype能大幅降低内存占用,避免内存溢出。
内容的提问来源于stack exchange,提问作者Nat
相关产品推荐
相关产品推荐

